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
109
110
111
112
113
114
115
116
117
118
// For more information about basic "External Term Format" types you can read
// on the next page: http://erlang.org/doc/apps/erts/erl_ext_dist.html
use std::string::String;
use std::ops::Deref;
use std::{i32};

use num::bigint::BigInt;

pub const BERT_LABEL: &'static str = "bert";
pub const EXT_VERSION: u8 = 131u8;


// The BERT encoding is identical to Erlang's external term format except that
// it is restricted to the following data type identifiers: 97-100, 104-111.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum BertTag {
    NewFloat = 70,      // 70, NEW_FLOAT_EXT

    SmallInteger = 97,  // 97, SMALL_INTEGER_EXT
    Integer = 98,       // 98, INTEGER_EXT
    Float = 99,         // 99, FLOAT_EXT (deprecated; using for deserialize)
    Atom = 100,         // 100, ATOM_EXT

    SmallTuple = 104,   // 104, SMALL_TUPLE_EXT
    LargeTuple = 105,   // 105, LARGE_TUPLE_EXT
    Nil = 106,          // 106, NIL_EXT
    String = 107,       // 107, STRING_EXT
    List = 108,         // 108, LIST_EXT
    Binary = 109,       // 109, BINARY_EXT
    SmallBigNum = 110,  // 110, SMALL_BIG_EXT
    LargeBigNum = 111,  // 111, LARGE_BIG_EXT
}


#[derive(Debug, PartialEq)]
pub struct BertBigInteger(pub BigInt);


impl Deref for BertBigInteger {
    type Target = BigInt;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


#[derive(Debug, PartialEq)]
pub struct BertTime(TimeStruct);


impl BertTime {
    pub fn new(megaseconds: i32, seconds: i32, microseconds: i32) -> BertTime {
        BertTime(
            TimeStruct{
                megaseconds: megaseconds,
                seconds: seconds,
                microseconds: microseconds
            }
        )
    }
}


impl Deref for BertTime {
    type Target = TimeStruct;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


#[derive(Debug, PartialEq)]
pub struct TimeStruct {
    pub megaseconds: i32,
    pub seconds: i32,
    pub microseconds: i32,
}


#[derive(Debug, PartialEq)]
pub struct BertRegex(RegexStruct);


impl BertRegex {
    pub fn new(source: &str, options: Vec<RegexOption>) -> BertRegex {
        BertRegex(
            RegexStruct{
                source: source.to_string(),
                options: options,
            }
        )
    }
}


impl Deref for BertRegex {
    type Target = RegexStruct;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


#[derive(Debug, PartialEq)]
pub struct RegexStruct {
    pub source: String,
    pub options: Vec<RegexOption>
}


enum_str!(
    RegexOption {
        Extended("extended"),
        Caseless("caseless"),
        Multiline("multiline"),
        DotAll("dotall"),
    }
);