1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ptr::P;

use fn_decl::FnDeclBuilder;
use generics::GenericsBuilder;
use invoke::{Invoke, Identity};

//////////////////////////////////////////////////////////////////////////////

pub struct MethodSigBuilder<F=Identity> {
    callback: F,
    span: Span,
    abi: Abi,
    generics: ast::Generics,
    unsafety: ast::Unsafety,
    constness: ast::Constness,
}

impl MethodSigBuilder {
    pub fn new() -> Self {
        MethodSigBuilder::with_callback(Identity)
    }
}

impl<F> MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    pub fn with_callback(callback: F) -> Self {
        MethodSigBuilder {
            callback: callback,
            span: DUMMY_SP,
            abi: Abi::Rust,
            generics: GenericsBuilder::new().build(),
            unsafety: ast::Unsafety::Normal,
            constness: ast::Constness::NotConst,
        }
    }

    pub fn span(mut self, span: Span) -> Self {
        self.span = span;
        self
    }

    pub fn unsafe_(mut self) -> Self {
        self.unsafety = ast::Unsafety::Normal;
        self
    }

    pub fn const_(mut self) -> Self {
        self.constness = ast::Constness::Const;
        self
    }

    pub fn abi(mut self, abi: Abi) -> Self {
        self.abi = abi;
        self
    }

    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
        self.generics = generics;
        self
    }

    pub fn generics(self) -> GenericsBuilder<Self> {
        GenericsBuilder::with_callback(self)
    }

    pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> F::Result {
        self.callback.invoke(ast::MethodSig {
            unsafety: self.unsafety,
            constness: self.constness,
            abi: self.abi,
            decl: fn_decl,
            generics: self.generics,
        })
    }

    pub fn fn_decl(self) -> FnDeclBuilder<Self> {
        FnDeclBuilder::with_callback(self)
    }
}

impl<F> Invoke<ast::Generics> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = Self;

    fn invoke(self, generics: ast::Generics) -> Self {
        self.with_generics(generics)
    }
}

impl<F> Invoke<P<ast::FnDecl>> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = F::Result;

    fn invoke(self, fn_decl: P<ast::FnDecl>) -> Self::Result {
        self.build_fn_decl(fn_decl)
    }
}