ps_driver_deserializer/
lib.rs

1use proc_macro::TokenStream;
2
3#[proc_macro_derive(Database)]
4pub fn derive_database(_input: TokenStream) -> TokenStream {
5    let input = syn::parse_macro_input!(_input as syn::DeriveInput);
6    let name = &input.ident;
7
8    if let syn::Data::Struct(data) = &input.data {
9        let fields = match &data.fields {
10            syn::Fields::Named(fields) => &fields.named,
11            _ => panic!("Only named fields are supported"),
12        };
13        let fields_len = syn::Index::from(fields.len());
14
15        let mut names = Vec::new();
16        let mut values = Vec::new();
17
18        for i in 0..fields.len() {
19            let field = &fields[i];
20
21            let name = &field.ident;
22            let ty = &field.ty;
23            names.push(name);
24
25            let index = syn::Index::from(i);
26            values.push(quote::quote! {
27                #ty::custom_parse(input[#index])?
28            });
29        }
30
31        let output = quote::quote! {
32            use planetscale_driver::Parser;
33            impl Deserializer for #name {
34                fn deserialize_raw(input: Vec<&str>) -> anyhow::Result<Self> {
35                    if input.len() != #fields_len {
36                        anyhow::bail!("Invalid number of fields");
37                    }
38
39                    Ok(Self {
40                        #(
41                            #names: #values,
42                        )*
43                    })
44                }
45            }
46        };
47
48        TokenStream::from(output)
49    } else {
50        panic!("Only structs are supported")
51    }
52}