serde_seeded_derive/
lib.rs1use attributes::FieldAttributes;
8use proc_macro::TokenStream;
9use proc_macro2::Span;
10use proc_macro_error::{abort, proc_macro_error};
11use quote::format_ident;
12use syn::{parse_macro_input, spanned::Spanned};
13
14pub(crate) mod attributes;
15mod de;
16mod ser;
17pub(crate) mod utils;
18
19#[proc_macro_derive(SerializeSeeded, attributes(seeded))]
23#[proc_macro_error]
24pub fn derive_serialize(input: TokenStream) -> TokenStream {
25 let input = parse_macro_input!(input as syn::DeriveInput);
26 match ser::derive(input) {
27 Ok(tokens) => tokens.into(),
28 Err(e) => {
29 abort!(e.span(), e.to_string())
30 }
31 }
32}
33
34#[proc_macro_derive(DeserializeSeeded, attributes(seeded))]
38#[proc_macro_error]
39pub fn derive_deserialize(input: TokenStream) -> TokenStream {
40 let input = parse_macro_input!(input as syn::DeriveInput);
41 match de::derive(input) {
42 Ok(tokens) => tokens.into(),
43 Err(e) => {
44 abort!(e.span(), e.to_string())
45 }
46 }
47}
48
49enum SerializedFields {
50 Unit,
51 Unnamed(Vec<SerializedUnnamedField>),
52 Named(Vec<SerializedNamedField>),
53}
54
55impl SerializedFields {
56 fn new(fields: &syn::Fields) -> Result<Self, attributes::Error> {
57 match fields {
58 syn::Fields::Unit => Ok(Self::Unit),
59 syn::Fields::Unnamed(fields) => fields
60 .unnamed
61 .iter()
62 .enumerate()
63 .map(|(i, f)| {
64 Ok(SerializedUnnamedField {
65 attrs: FieldAttributes::parse_attributes(&f.attrs)?,
66 index: i.into(),
67 id: format_ident!("arg_{i}"),
68 ty: f.ty.clone(),
69 })
70 })
71 .collect::<Result<_, _>>()
72 .map(Self::Unnamed),
73 syn::Fields::Named(fields) => fields
74 .named
75 .iter()
76 .map(|f| {
77 Ok(SerializedNamedField {
78 attrs: FieldAttributes::parse_attributes(&f.attrs)?,
79 id: f.ident.clone().unwrap(),
80 ty: f.ty.clone(),
81 span: f.span(),
82 })
83 })
84 .collect::<Result<_, _>>()
85 .map(Self::Named),
86 }
87 }
88}
89
90struct SerializedUnnamedField {
91 attrs: FieldAttributes,
92 index: syn::Index,
93 id: syn::Ident,
94 ty: syn::Type,
95}
96
97struct SerializedNamedField {
98 attrs: FieldAttributes,
99 id: syn::Ident,
100 ty: syn::Type,
101 span: Span,
102}
103
104impl SerializedNamedField {
105 pub fn name(&self) -> String {
106 self.attrs.name(&self.id)
107 }
108}