Skip to main content

ppbert/
bertterm.rs

1use num_bigint::{BigInt};
2
3/// A enum representing a BertTerm
4#[derive(Debug, PartialEq)]
5pub enum BertTerm {
6    /// The empty list
7    Nil,
8
9    /// A signed 32-bit integer
10    Int(i32),
11
12    /// A signed arbitrary-size integer
13    BigInt(BigInt),
14
15    /// A double-precision floating point number
16    Float(f64),
17
18    /// An atom
19    Atom(String),
20
21    /// A latin-1-encoded string
22    String(Vec<u8>),
23
24    /// An array of bytes
25    Binary(Vec<u8>),
26
27    /// A container for a fixed number of elements
28    Tuple(Vec<BertTerm>),
29
30    /// A container for an arbitrary number of elements
31    List(Vec<BertTerm>),
32
33    /// A container for key-to-value pairs
34    Map(Vec<BertTerm>, Vec<BertTerm>),
35
36}
37
38impl BertTerm {
39    /// Lists, tuples, and maps are not basic terms;
40    /// everything else is.
41    pub fn is_basic(&self) -> bool {
42        match *self {
43            BertTerm::Int(_)
44            | BertTerm::BigInt(_)
45            | BertTerm::Float(_)
46            | BertTerm::Atom(_)
47            | BertTerm::String(_)
48            | BertTerm::Binary(_)
49            | BertTerm::Nil => true,
50            BertTerm::List(_)
51            | BertTerm::Tuple(_)
52            | BertTerm::Map(_, _) => false
53        }
54    }
55
56    /// A term is a proplist if it has this shape:
57    /// [ {atom|string|binary, term}* ]
58    pub fn is_proplist(&self) -> bool {
59        fn is_proplist_tuple(elems: &[BertTerm]) -> bool {
60            match elems {
61                [BertTerm::Atom(_), _] => true,
62                [BertTerm::String(_), _] => true,
63                [BertTerm::Binary(_), _] => true,
64                _ => false
65            }
66        }
67
68        fn is_proplist_entry(t: &BertTerm) -> bool {
69            match *t {
70                BertTerm::Tuple(ref elems) => is_proplist_tuple(elems),
71                _ => false
72            }
73        }
74
75        match *self {
76            BertTerm::List(ref elems) =>
77                elems.iter().all(|e| is_proplist_entry(e)),
78            _ => false
79        }
80    }
81}