1 | use proc_macro2::TokenStream as TokenStream2; |
2 | use quote::quote; |
3 | use syn::{DataStruct, Ident, ImplGenerics, TypeGenerics, WhereClause, WherePredicate}; |
4 | |
5 | pub(crate) use enum_data::encode as encode_enum_data; |
6 | |
7 | use crate::construct; |
8 | |
9 | mod enum_data; |
10 | mod fields; |
11 | |
12 | pub(crate) struct EncodeData { |
13 | pub(crate) format_tag: TokenStream2, |
14 | pub(crate) stmts: Vec<TokenStream2>, |
15 | pub(crate) where_predicates: Vec<WherePredicate>, |
16 | } |
17 | |
18 | pub(crate) fn encode_struct_data( |
19 | ident: &Ident, |
20 | data: &DataStruct, |
21 | defmt_path: &syn::Path, |
22 | ) -> syn::Result<EncodeData> { |
23 | let mut format_string = ident.to_string(); |
24 | let mut stmts = vec![]; |
25 | let mut field_patterns = vec![]; |
26 | |
27 | let (encode_fields_stmts, where_predicates) = fields::codegen( |
28 | &data.fields, |
29 | &mut format_string, |
30 | &mut field_patterns, |
31 | defmt_path, |
32 | )?; |
33 | |
34 | stmts.push(quote!(match self { |
35 | Self { #(#field_patterns),* } => { |
36 | #(#encode_fields_stmts;)* |
37 | } |
38 | })); |
39 | |
40 | let format_tag = construct::interned_string(&format_string, "derived" , false, None, defmt_path); |
41 | Ok(EncodeData { |
42 | format_tag, |
43 | stmts, |
44 | where_predicates, |
45 | }) |
46 | } |
47 | |
48 | pub(crate) struct Generics<'a> { |
49 | pub(crate) impl_generics: ImplGenerics<'a>, |
50 | pub(crate) type_generics: TypeGenerics<'a>, |
51 | pub(crate) where_clause: WhereClause, |
52 | } |
53 | |
54 | impl<'a> Generics<'a> { |
55 | pub(crate) fn codegen( |
56 | generics: &'a mut syn::Generics, |
57 | where_predicates: Vec<WherePredicate>, |
58 | ) -> Self { |
59 | let mut where_clause: WhereClause = generics.make_where_clause().clone(); |
60 | let (impl_generics: ImplGenerics<'_>, type_generics: TypeGenerics<'_>, _) = generics.split_for_impl(); |
61 | |
62 | // Extend where-clause with `Format` bounds for all field types. |
63 | where_clause.predicates.extend(iter:where_predicates); |
64 | |
65 | Self { |
66 | impl_generics, |
67 | type_generics, |
68 | where_clause, |
69 | } |
70 | } |
71 | } |
72 | |