Skip to main content

bel/common/types/
mod.rs

1use crate::common::traits;
2
3mod bool;
4mod bytes;
5mod duration;
6mod float;
7mod int;
8mod null;
9mod optional;
10mod string;
11mod timestamp;
12// mod uint;
13
14pub use bool::Bool;
15pub use bytes::Bytes;
16pub use duration::Duration;
17pub use float::Float;
18pub use int::Int;
19pub use null::Null;
20pub use string::String;
21pub use timestamp::Timestamp;
22// pub use uint::UInt;
23
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum Kind {
26    Unspecified,
27    Error,
28    Dyn,
29    Any,
30    Boolean,
31    Bytes,
32    Float,
33    Duration,
34    Int,
35    List,
36    Map,
37    NullType,
38    Opaque,
39    String,
40    Struct,
41    Timestamp,
42    Type,
43    TypeParam,
44    UInt,
45    Unknown,
46}
47
48#[derive(Clone, Debug, Eq, PartialEq)]
49pub struct Type<'a> {
50    kind: Kind,
51    parameters: &'a [&'a Type<'a>],
52    runtime_type_name: &'a str,
53    trait_mask: u16,
54}
55
56pub const ANY_TYPE: Type = Type {
57    kind: Kind::Any,
58    parameters: &[],
59    runtime_type_name: "google.protobuf.Any",
60    trait_mask: traits::FIELD_TESTER_TYPE | traits::INDEXER_TYPE,
61};
62
63pub const BOOL_TYPE: Type = Type {
64    kind: Kind::Boolean,
65    parameters: &[],
66    runtime_type_name: "bool",
67    trait_mask: traits::COMPARER_TYPE | traits::NEGATOR_TYPE,
68};
69
70pub const BYTES_TYPE: Type = Type {
71    kind: Kind::Bytes,
72    parameters: &[],
73    runtime_type_name: "bytes",
74    trait_mask: traits::ADDER_TYPE | traits::COMPARER_TYPE | traits::SIZER_TYPE,
75};
76
77pub const FLOAT_TYPE: Type = Type {
78    kind: Kind::Float,
79    parameters: &[],
80    runtime_type_name: "float",
81    trait_mask: traits::ADDER_TYPE
82        | traits::COMPARER_TYPE
83        | traits::DIVIDER_TYPE
84        | traits::MULTIPLIER_TYPE
85        | traits::NEGATOR_TYPE
86        | traits::SUBTRACTOR_TYPE,
87};
88
89pub const DURATION_TYPE: Type = Type {
90    kind: Kind::Duration,
91    parameters: &[],
92    runtime_type_name: "google.protobuf.Duration",
93    trait_mask: traits::ADDER_TYPE
94        | traits::COMPARER_TYPE
95        | traits::NEGATOR_TYPE
96        | traits::RECEIVER_TYPE
97        | traits::SUBTRACTOR_TYPE,
98};
99
100pub const DYN_TYPE: Type = Type::simple_type(Kind::Dyn, "dyn");
101
102pub const ERROR_TYPE: Type = Type::simple_type(Kind::Error, "error");
103
104pub const INT_TYPE: Type = Type {
105    kind: Kind::Int,
106    parameters: &[],
107    runtime_type_name: "int",
108    trait_mask: traits::ADDER_TYPE
109        | traits::COMPARER_TYPE
110        | traits::DIVIDER_TYPE
111        | traits::MODDER_TYPE
112        | traits::MULTIPLIER_TYPE
113        | traits::NEGATOR_TYPE
114        | traits::SUBTRACTOR_TYPE,
115};
116
117pub const LIST_TYPE: Type = Type::new_list_type(&[&DYN_TYPE]);
118
119pub const MAP_TYPE: Type = Type::new_map_type(&[&DYN_TYPE, &DYN_TYPE]);
120
121pub const NULL_TYPE: Type = Type::simple_type(Kind::NullType, "null_type");
122
123pub const STRING_TYPE: Type = Type {
124    kind: Kind::String,
125    parameters: &[],
126    runtime_type_name: "string",
127    trait_mask: traits::ADDER_TYPE
128        | traits::COMPARER_TYPE
129        | traits::MATCHER_TYPE
130        | traits::RECEIVER_TYPE
131        | traits::SIZER_TYPE,
132};
133
134pub const TIMESTAMP_TYPE: Type = Type {
135    kind: Kind::Timestamp,
136    parameters: &[],
137    runtime_type_name: "google.protobuf.Timestamp",
138    trait_mask: traits::ADDER_TYPE | traits::COMPARER_TYPE | traits::RECEIVER_TYPE | traits::SUBTRACTOR_TYPE,
139};
140
141pub const TYPE_TYPE: Type = Type::simple_type(Kind::Type, "type");
142
143pub const UINT_TYPE: Type = Type {
144    kind: Kind::UInt,
145    parameters: &[],
146    runtime_type_name: "uint",
147    trait_mask: traits::ADDER_TYPE
148        | traits::COMPARER_TYPE
149        | traits::DIVIDER_TYPE
150        | traits::MODDER_TYPE
151        | traits::MULTIPLIER_TYPE
152        | traits::SUBTRACTOR_TYPE,
153};
154
155pub const UNKNOWN_TYPE: Type = Type::simple_type(Kind::Unknown, "unknown");
156
157impl<'a> Type<'a> {
158    pub const fn simple_type(kind: Kind, name: &str) -> Type<'_> {
159        Type {
160            kind,
161            parameters: &[],
162            runtime_type_name: name,
163            trait_mask: 0,
164        }
165    }
166
167    pub const fn new_list_type<'b>(param: &'b [&'b Type<'b>; 1]) -> Type<'b> {
168        Type {
169            kind: Kind::List,
170            parameters: param,
171            runtime_type_name: "list",
172            trait_mask: traits::ADDER_TYPE
173                | traits::CONTAINER_TYPE
174                | traits::INDEXER_TYPE
175                | traits::ITERABLE_TYPE
176                | traits::SIZER_TYPE,
177        }
178    }
179
180    pub const fn new_map_type<'b>(param: &'b [&'b Type<'b>; 2]) -> Type<'b> {
181        Type {
182            kind: Kind::Map,
183            parameters: param,
184            runtime_type_name: "map",
185            trait_mask: traits::CONTAINER_TYPE | traits::INDEXER_TYPE | traits::ITERABLE_TYPE | traits::SIZER_TYPE,
186        }
187    }
188
189    pub const fn new_unspecified_type(name: &str) -> Type<'_> {
190        Type {
191            kind: Kind::Unspecified,
192            parameters: &[],
193            runtime_type_name: name,
194            trait_mask: 0,
195        }
196    }
197
198    pub const fn new_opaque_type(name: &str) -> Type<'_> {
199        Type {
200            kind: Kind::Opaque,
201            parameters: &[],
202            runtime_type_name: name,
203            trait_mask: 0,
204        }
205    }
206
207    pub fn name(&self) -> &'a str {
208        self.runtime_type_name
209    }
210
211    pub fn has_trait(&self, t: u16) -> bool {
212        self.trait_mask & t == t
213    }
214}
215
216#[cfg(test)]
217mod tests {
218    use super::*;
219
220    #[test]
221    fn parameterized_type() {
222        let param = Type {
223            kind: Kind::Unspecified,
224            parameters: &[],
225            runtime_type_name: "",
226            trait_mask: 0,
227        };
228
229        let t = std::string::String::from("List");
230        let parameterized_list = Type {
231            kind: Kind::List,
232            parameters: &[&param],
233            runtime_type_name: &t,
234            trait_mask: 0,
235        };
236        assert_eq!(&param, parameterized_list.parameters[0]);
237
238        let params = [&param];
239        let list2 = Type::new_list_type(&params);
240        assert_eq!(&param, list2.parameters[0]);
241        assert_eq!(1, list2.parameters.len());
242
243        let params = [&param, &param];
244        let map = Type::new_map_type(&params);
245        assert_eq!(&param, map.parameters[0]);
246        assert_eq!(&param, map.parameters[1]);
247        assert_eq!(2, map.parameters.len());
248    }
249}