darkfi_derive_internal/
lib.rs1use std::collections::HashMap;
21
22use proc_macro2::{Ident, TokenStream};
23use quote::quote;
24use syn::{punctuated::Punctuated, token::Comma, Attribute, Path, Variant, WherePredicate};
25
26mod sync_derive;
27pub use sync_derive::{enum_de, enum_ser, struct_de, struct_ser};
28
29#[cfg(feature = "async")]
30mod async_derive;
31#[cfg(feature = "async")]
32pub use async_derive::{async_enum_de, async_enum_ser, async_struct_de, async_struct_ser};
33
34struct VariantParts {
35 where_predicates: Vec<WherePredicate>,
36 variant_header: TokenStream,
37 variant_body: TokenStream,
38 variant_idx_body: TokenStream,
39}
40
41fn discriminant_map(variants: &Punctuated<Variant, Comma>) -> HashMap<Ident, TokenStream> {
44 let mut map = HashMap::new();
45
46 let mut next_discriminant_if_not_specified = quote! {0};
47
48 for variant in variants {
49 let this_discriminant = variant
50 .discriminant
51 .clone()
52 .map_or_else(|| quote! { #next_discriminant_if_not_specified }, |(_, e)| quote! { #e });
53
54 next_discriminant_if_not_specified = quote! { #this_discriminant + 1 };
55 map.insert(variant.ident.clone(), this_discriminant);
56 }
57
58 map
59}
60
61pub fn contains_skip(attrs: &[Attribute]) -> bool {
62 attrs.iter().any(|attr| attr.path().is_ident("skip_serialize"))
63}
64
65pub fn contains_initialize_with(attrs: &[Attribute]) -> Option<Path> {
66 for attr in attrs.iter() {
67 if attr.path().is_ident("init_serialize") {
68 let mut res = None;
69 let _ = attr.parse_nested_meta(|meta| {
70 res = Some(meta.path);
71 Ok(())
72 });
73 return res
74 }
75 }
76
77 None
78}