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
104
105
106
107
108
use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ptr::P;

use invoke::{Invoke, Identity};

use str::ToInternedString;

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

pub struct LitBuilder<F=Identity> {
    callback: F,
    span: Span,
}

impl LitBuilder {
    pub fn new() -> LitBuilder {
        LitBuilder::new_with_callback(Identity)
    }
}

impl<F> LitBuilder<F>
    where F: Invoke<P<ast::Lit>>,
{
    pub fn new_with_callback(callback: F) -> Self {
        LitBuilder {
            callback: callback,
            span: DUMMY_SP,
        }
    }

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

    pub fn build_lit(self, lit: ast::Lit_) -> F::Result {
        self.callback.invoke(P(ast::Lit {
            span: self.span,
            node: lit,
        }))
    }

    pub fn bool(self, value: bool) -> F::Result {
        self.build_lit(ast::LitBool(value))
    }

    pub fn int(self, value: i64) -> F::Result {
        let sign = ast::Sign::new(value);
        self.build_lit(ast::LitInt(value as u64, ast::UnsuffixedIntLit(sign)))
    }

    fn build_int(self, value: i64, ty: ast::IntTy) -> F::Result {
        let sign = ast::Sign::new(value);
        self.build_lit(ast::LitInt(value as u64, ast::LitIntType::SignedIntLit(ty, sign)))
    }

    pub fn isize(self, value: isize) -> F::Result {
        self.build_int(value as i64, ast::IntTy::TyIs)
    }

    pub fn i8(self, value: i8) -> F::Result {
        self.build_int(value as i64, ast::IntTy::TyI8)
    }

    pub fn i16(self, value: i16) -> F::Result {
        self.build_int(value as i64, ast::IntTy::TyI16)
    }

    pub fn i32(self, value: i32) -> F::Result {
        self.build_int(value as i64, ast::IntTy::TyI32)
    }

    pub fn i64(self, value: i64) -> F::Result {
        self.build_int(value, ast::IntTy::TyI64)
    }

    fn build_uint(self, value: u64, ty: ast::UintTy) -> F::Result {
        self.build_lit(ast::LitInt(value, ast::LitIntType::UnsignedIntLit(ty)))
    }

    pub fn usize(self, value: usize) -> F::Result {
        self.build_uint(value as u64, ast::UintTy::TyUs)
    }

    pub fn u8(self, value: u8) -> F::Result {
        self.build_uint(value as u64, ast::UintTy::TyU8)
    }

    pub fn u16(self, value: u16) -> F::Result {
        self.build_uint(value as u64, ast::UintTy::TyU16)
    }

    pub fn u32(self, value: u32) -> F::Result {
        self.build_uint(value as u64, ast::UintTy::TyU32)
    }

    pub fn u64(self, value: u64) -> F::Result {
        self.build_uint(value, ast::UintTy::TyU64)
    }

    pub fn str<S>(self, value: S) -> F::Result
        where S: ToInternedString,
    {
        let value = value.to_interned_string();
        self.build_lit(ast::LitStr(value, ast::CookedStr))
    }
}