gull/definitions/
builders.rs

1#![allow(clippy::return_self_not_must_use)]
2
3use super::*;
4use std::iter::IntoIterator;
5
6macro_rules! unwrap_opt {
7    ( $builder:ident,  $optional_field:ident ) => {{
8        let unwrapped = $builder.$optional_field.clone().expect(&format!(
9            "
10            ```````````````````````````````````````````````
11            Builder is not finished because the value of the
12            field `{}` is not set.
13            Builder: `{:?}`\n
14            ```````````````````````````````````````````````
15            ",
16            stringify!($optional_field),
17            &$builder,
18        ));
19        unwrapped
20    }};
21}
22
23/********************************************************************************/
24/********************************************************************************/
25/********************************************************************************/
26
27pub fn decl<'a>(d: &'a mut Declarations, name: &'static str) -> TypeDeclarationBuilder<'a> {
28    TypeDeclarationBuilder {
29        d,
30        name,
31        docs: "",
32        value: None,
33        config: vec![build_derives(vec![
34            "serde::Serialize",
35            "serde::Deserialize",
36            "Debug",
37            "Clone",
38        ])],
39        generic_params: vec![],
40    }
41}
42
43#[derive(Debug)]
44pub struct TypeDeclarationBuilder<'a> {
45    d: &'a mut Declarations,
46    name: &'static str,
47    docs: &'static str,
48    value: Option<DeclarationValue>,
49    config: Vec<TypeDeclarationConfig>,
50    generic_params: Vec<TGeneric>,
51}
52
53impl<'a> TypeDeclarationBuilder<'a> {
54    pub fn value<T: Into<DeclarationValue>>(mut self, value: T) -> Self {
55        self.value = Some(value.into());
56        self
57    }
58
59    pub fn build(self) -> TReference {
60        self.d.add(TypeDeclaration {
61            name: self.name,
62            docs: self.docs,
63            value: unwrap_opt!(self, value),
64            config: self.config,
65            generic_params: self.generic_params,
66        })
67    }
68}
69
70/********************************************************************************/
71/********************************************************************************/
72/********************************************************************************/
73
74impl From<TStruct> for DeclarationValue {
75    fn from(s: TStruct) -> Self {
76        DeclarationValue::TStruct(s)
77    }
78}
79
80impl From<TEnum> for DeclarationValue {
81    fn from(s: TEnum) -> Self {
82        DeclarationValue::TEnum(s)
83    }
84}
85/********************************************************************************/
86/********************************************************************************/
87/********************************************************************************/
88
89pub fn build_struct() -> TStructBuilder {
90    TStructBuilder { fields: vec![] }
91}
92
93#[derive(Debug, Clone)]
94pub struct TStructBuilder {
95    pub fields: Vec<StructField>,
96}
97
98impl TStructBuilder {
99    pub fn build(self) -> TStruct {
100        TStruct {
101            fields: self.fields,
102        }
103    }
104}
105
106impl TStructBuilder {
107    pub fn field(mut self, f: StructField) -> Self {
108        self.fields.push(f);
109        self
110    }
111
112    pub fn fields(self, fields: impl IntoIterator<Item = StructField>) -> Self {
113        let mut s = self;
114        for f in fields {
115            s = s.field(f)
116        }
117        s
118    }
119}
120
121impl TStruct {
122    pub fn decl(self) -> DeclarationValue {
123        DeclarationValue::TStruct(self)
124    }
125}
126
127/********************************************************************************/
128/********************************************************************************/
129/********************************************************************************/
130
131pub fn build_struct_field(name: &'static str) -> StructFieldBuilder {
132    StructFieldBuilder {
133        name,
134        ..Default::default()
135    }
136}
137
138#[derive(Default, Debug)]
139pub struct StructFieldBuilder {
140    name: &'static str,
141    pub docs: &'static str,
142    pub field_type: Option<StructFieldType>,
143    pub config: Vec<StructFieldConfig>,
144}
145
146impl StructFieldBuilder {
147    pub fn build(self) -> StructField {
148        StructField {
149            name: self.name,
150            docs: self.docs,
151            field_type: unwrap_opt!(self, field_type),
152            config: self.config,
153        }
154    }
155
156    pub fn field_type<T: Into<StructFieldType>>(mut self, t: T) -> Self {
157        self.field_type = Some(t.into());
158        self
159    }
160
161    pub fn optional(mut self) -> Self {
162        let field_type = self
163            .field_type
164            .expect("must set field type before making it optional");
165        let field_type = match field_type {
166            StructFieldType::TMap(map) => StructFieldType::TOption(TOption::TMap(map)),
167            StructFieldType::TSet(set) => StructFieldType::TOption(TOption::TSet(set)),
168            StructFieldType::TOption(opt) => StructFieldType::TOption(opt),
169            StructFieldType::TPrimitive(p) => StructFieldType::TOption(TOption::TPrimitive(p)),
170            StructFieldType::TTuple(t) => StructFieldType::TOption(TOption::TTuple(t)),
171            StructFieldType::TVec(v) => StructFieldType::TOption(TOption::TVec(v)),
172        };
173        self.field_type = Some(field_type);
174        self
175    }
176}
177
178impl From<TPrimitive> for StructFieldType {
179    fn from(p: TPrimitive) -> Self {
180        StructFieldType::TPrimitive(p)
181    }
182}
183
184impl From<TVec> for StructFieldType {
185    fn from(v: TVec) -> Self {
186        StructFieldType::TVec(v)
187    }
188}
189
190impl From<TMap> for StructFieldType {
191    fn from(v: TMap) -> Self {
192        StructFieldType::TMap(v)
193    }
194}
195
196impl From<TSet> for StructFieldType {
197    fn from(v: TSet) -> Self {
198        StructFieldType::TSet(v)
199    }
200}
201
202impl From<TReference> for StructFieldType {
203    fn from(v: TReference) -> Self {
204        StructFieldType::TPrimitive(v.primitive())
205    }
206}
207
208/********************************************************************************/
209/********************************************************************************/
210/********************************************************************************/
211
212pub fn build_enum() -> TEnumBuilder {
213    TEnumBuilder { variants: vec![] }
214}
215
216pub struct TEnumBuilder {
217    variants: Vec<EnumVariant>,
218}
219
220impl TEnumBuilder {
221    pub fn build(self) -> TEnum {
222        TEnum {
223            variants: self.variants,
224        }
225    }
226
227    pub fn variant(mut self, v: EnumVariant) -> Self {
228        self.variants.push(v);
229        self
230    }
231
232    pub fn variants(self, variants: impl IntoIterator<Item = EnumVariant>) -> Self {
233        let mut s = self;
234        for v in variants {
235            s = s.variant(v)
236        }
237        s
238    }
239}
240
241/********************************************************************************/
242/********************************************************************************/
243/********************************************************************************/
244
245pub fn build_enum_variant(name: &'static str) -> EnumVariantBuilder {
246    EnumVariantBuilder {
247        name,
248        docs: "",
249        variant_type: None,
250    }
251}
252
253#[derive(Debug)]
254pub struct EnumVariantBuilder {
255    pub name: &'static str,
256    pub docs: &'static str,
257    pub variant_type: Option<EnumVariantType>,
258}
259
260impl EnumVariantBuilder {
261    pub fn build(self) -> EnumVariant {
262        EnumVariant {
263            name: self.name,
264            docs: self.docs,
265            variant_type: unwrap_opt!(self, variant_type),
266        }
267    }
268
269    pub fn variant_type<T: Into<EnumVariantType>>(mut self, t: T) -> Self {
270        self.variant_type = Some(t.into());
271        self
272    }
273}
274
275/********************************************************************************/
276/********************************************************************************/
277/********************************************************************************/
278
279impl From<TPrimitive> for EnumVariantType {
280    fn from(p: TPrimitive) -> Self {
281        EnumVariantType::TPrimitive(p)
282    }
283}
284
285impl From<TReference> for EnumVariantType {
286    fn from(p: TReference) -> Self {
287        EnumVariantType::TPrimitive(p.primitive())
288    }
289}
290
291impl From<TStruct> for EnumVariantType {
292    fn from(s: TStruct) -> Self {
293        EnumVariantType::TStruct(s)
294    }
295}
296
297/********************************************************************************/
298/********************************************************************************/
299/********************************************************************************/
300
301pub fn build_vec<T: Into<TPrimitive>>(t: T) -> TVec {
302    TVec::TPrimitive(t.into())
303}
304
305pub fn build_map<K: Into<TPrimitive>, V: Into<TPrimitive>>(k: K, v: V) -> TMap {
306    TMap {
307        key: k.into(),
308        value: TMapValue::TPrimitive(v.into()),
309        t: TMapType::BTree,
310    }
311}
312
313pub fn build_set<T: Into<TPrimitive>>(t: T) -> TSet {
314    TSet::TPrimitive(t.into())
315}
316
317/********************************************************************************/
318/********************************************************************************/
319/********************************************************************************/
320
321impl From<TReference> for TPrimitive {
322    fn from(t: TReference) -> Self {
323        t.primitive()
324    }
325}
326
327/********************************************************************************/
328/********************************************************************************/
329/********************************************************************************/
330
331pub fn build_derives(derives: Vec<&str>) -> TypeDeclarationConfig {
332    let derives = derives
333        .iter()
334        .map(|s| s.to_string())
335        .collect::<Vec<_>>()
336        .join(", ");
337    let s = Box::leak(format!("#[derive({})]", derives).into_boxed_str());
338    TypeDeclarationConfig::RustAttribute(s)
339}
340/********************************************************************************/
341/********************************************************************************/
342/********************************************************************************/