molecule_codegen/generator/languages/rust/builder/
definition.rs

1use proc_macro2 as m4;
2use quote::quote;
3
4use super::super::utilities::{
5    builder_name, entity_name, entity_union_name, field_name, usize_lit,
6};
7use crate::ast::{self as ast, HasName};
8
9pub(in super::super) trait DefBuilder {
10    fn def_builder(&self) -> m4::TokenStream;
11}
12
13impl DefBuilder for ast::Option_ {
14    fn def_builder(&self) -> m4::TokenStream {
15        let builder = builder_name(self.name());
16        let inner = entity_name(self.item().typ().name());
17        quote!(
18            #[derive(Clone, Debug, Default)]
19            pub struct #builder (pub(crate) Option<#inner>);
20        )
21    }
22}
23
24impl DefBuilder for ast::Union {
25    fn def_builder(&self) -> m4::TokenStream {
26        let builder = builder_name(self.name());
27        let entity_union = entity_union_name(self.name());
28        quote!(
29            #[derive(Clone, Debug, Default)]
30            pub struct #builder (pub(crate) #entity_union);
31        )
32    }
33}
34
35impl DefBuilder for ast::Array {
36    fn def_builder(&self) -> m4::TokenStream {
37        let builder = builder_name(self.name());
38        let inner = entity_name(self.item().typ().name());
39        let item_count = usize_lit(self.item_count());
40        let inner_array = (0..self.item_count())
41            .map(|_| inner.clone())
42            .collect::<Vec<_>>();
43        quote!(
44            #[derive(Clone)]
45            pub struct #builder (pub(crate) [#inner; #item_count]);
46
47            impl ::core::fmt::Debug for #builder {
48                fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
49                    write!(f, "{}({:?})", Self::NAME, &self.0[..])
50                }
51            }
52
53            impl ::core::default::Default for #builder {
54                fn default() -> Self {
55                    #builder([#(#inner_array::default(), )*])
56                }
57            }
58        )
59    }
60}
61
62impl DefBuilder for ast::Struct {
63    fn def_builder(&self) -> m4::TokenStream {
64        def_builder_for_struct_or_table(self.name(), self.fields())
65    }
66}
67
68impl DefBuilder for ast::FixVec {
69    fn def_builder(&self) -> m4::TokenStream {
70        def_builder_for_vector(self.name(), self.item().typ().name())
71    }
72}
73
74impl DefBuilder for ast::DynVec {
75    fn def_builder(&self) -> m4::TokenStream {
76        def_builder_for_vector(self.name(), self.item().typ().name())
77    }
78}
79
80impl DefBuilder for ast::Table {
81    fn def_builder(&self) -> m4::TokenStream {
82        def_builder_for_struct_or_table(self.name(), self.fields())
83    }
84}
85
86fn def_builder_for_struct_or_table(self_name: &str, inner: &[ast::FieldDecl]) -> m4::TokenStream {
87    let builder = builder_name(self_name);
88    let fields = inner.iter().map(|f| {
89        let field_name = field_name(f.name());
90        let field_type = entity_name(f.typ().name());
91        quote!(#field_name: #field_type,)
92    });
93    quote!(
94        #[derive(Clone, Debug, Default)]
95        pub struct #builder { #( pub(crate) #fields )* }
96    )
97}
98
99fn def_builder_for_vector(self_name: &str, inner_name: &str) -> m4::TokenStream {
100    let builder = builder_name(self_name);
101    let inner = entity_name(inner_name);
102    quote!(
103        #[derive(Clone, Debug, Default)]
104        pub struct #builder (pub(crate) Vec<#inner>);
105    )
106}