| 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 | |