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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use std::collections::HashMap;

use crate::types::ident::ValueIdent;

#[derive(Debug, Clone, PartialOrd)]
/// A numerical value tag, used when creating tycho data.
pub enum Number {
    Bit(bool),
    Unsigned8(u8),
    Signed8(i8),
    Unsigned16(u16),
    Signed16(i16),
    Unsigned32(u32),
    Signed32(i32),
    Unsigned64(u64),
    Signed64(i64),
    Unsigned128(u128),
    Signed128(i128),
    Float32(f32),
    Float64(f64)
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq)]
/// A primitive terminating type, used when creating tycho data.
///
/// Values can contains numerical values using [numbers](crate::Number)
pub enum Value {
    /// A null value, representing no data.
    ///
    /// Used as a placeholder type.
    /// When handling no data, use a unit instead.
    Null,

    /// A boolean value representing `true` or `false`.
    Boolean(bool),

    /// A UTF-8 length prefixed string.
    String(String),

    /// A single UTF-8 character, (not length or terminated)
    Char(char),

    /// A numerical value.
    Number(Number),

    /// A length prefixed set of unsigned octet bytes.
    Bytes(Vec<u8>),

    /// A 16 bytes unique identifier
    UUID(uuid::Uuid),
}

#[derive(Debug, Clone, PartialEq)]
/// A element tag, used to build tycho data structures.
///
/// Elements represent zero, one or multiple pieces of data.
/// They are non-primitive non-terminating and have the ability to contain typed and
/// untyped values or elements.
pub enum Element {
    /// ### Unit
    /// A element representing no data.
    ///
    /// Units are used when serializing from the following types:
    /// - Unit Struct (`struct Foo;`)
    /// - Unit Variant (`enum Foo { Bar, Baz }`)
    /// - Unit (`()`)
    Unit,

    /// ### Value
    /// A element representing a primitive value.
    ///
    /// A value element contains a [`Value`](crate::Value) object as its payload.
    /// Data structures that only contain a value with be prefixed with the ValueIdent.
    ///
    /// A value can represent any of the following types:
    /// - `bool`
    /// - `&str`,
    /// - `String`
    /// - `char`
    /// - `number` - `u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64`
    /// - `bytes` - `Vec<u8>`
    Value(Value),

    /// ### Option
    /// An element representing a Some or None value.
    ///
    /// This element maps directly to Rust `Option<T>` type,
    /// and can have a payload of an element when some.
    Option(Option<Box<Element>>),

    /// ### Variant
    /// An element representing a named variable type.
    ///
    /// This element represents a rust enum.
    ///
    /// #### Unit Variants
    /// e.g. `enum Example { Foo, Bar, Baz }`
    ///
    /// A unit variant is a enum with no data.
    ///
    /// Within tycho, the value `Example::Foo` would be represented as `Variant("Foo", Unit)`
    ///
    /// #### Value Variants
    /// e.g. `enum Example { Foo(String), Bar(bool), Baz(u8) }`
    ///
    /// A 'new type' enum containing a single piece of data.
    ///
    /// Within tycho, the value `Example::Bar(false)` would be represented as `Variant("Bar", Value(Bool(0)))`
    ///
    /// #### Tuple Variants
    /// e.g. `enum Example { Foo(u8, bool), Bar(u16, bool), Baz(u32, bool) }`
    ///
    /// A 'tuple' enum containing a multiple unnamed pieces of data.
    ///
    /// Within tycho, the value `Example::Baz(10, true)` would be represented as:
    /// `Variant("Baz, List([Value(Unsigned32(10)), Value(Bool(1)]))`
    ///
    /// #### Struct Variants
    /// e.g. `enum Example { Foo { bar: char } }`
    ///
    /// A 'tuple' enum containing a multiple unnamed pieces of data.
    ///
    /// Within tycho, the value `Example::Foo { bar: 'P'}` would be represented as:
    /// `Variant("Baz, Struct({"bar": Value(Char('P'))))`
    ///
    Variant(String, Box<Element>),

    /// ### Struct
    /// An element representing an untyped string key - element paring.
    ///
    /// Directly maps to rusts `struct` object within the serialisation process.
    Struct(HashMap<String, Element>),

    /// ### List
    /// An element representing an untyped collection of elements.
    ///
    /// Directly maps to any tuple or heterogeneous array.
    List(Vec<Element>),

    /// ### Array
    /// An element representing a strictly typed collection of values.
    ///
    /// Unlike lists, arrays can only store terminating values and homogeneous.
    Array(ValueIdent, Vec<Value>),

    /// ### Map
    /// An element representing a strictly typed key - to untyped element pair.
    ///
    /// They key of a map can be any terminating value, and is strictly typed.
    /// The value of a map can be any element and is homogeneous.
    Map(ValueIdent, HashMap<Value, Element>),

    /// ### Compression Marker
    /// Contains an element that will be g-zip compressed.
    #[cfg(feature="compression")]
    Compression(Box<Element>),
    #[cfg(not(feature="compression"))]
    Compression(Vec<u8>),
}