planetscale_driver_macros/
lib.rs1use 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 impl planetscale_driver::Deserializer for #name {
33 fn deserialize_raw(input: Vec<&str>) -> anyhow::Result<Self> {
34 use planetscale_driver::Parser;
35
36 if input.len() != #fields_len {
37 anyhow::bail!("Invalid number of fields");
38 }
39
40 Ok(Self {
41 #(
42 #names: #values,
43 )*
44 })
45 }
46 }
47 };
48
49 TokenStream::from(output)
50 } else {
51 panic!("Only structs are supported")
52 }
53}
54
55#[proc_macro_derive(DatabaseJSON)]
56pub fn derive_database_json(_input: TokenStream) -> TokenStream {
57 let input = syn::parse_macro_input!(_input as syn::DeriveInput);
58 let name = &input.ident;
59
60 if let syn::Data::Struct(_) = &input.data {
61 let output = quote::quote! {
62 impl planetscale_driver::Parser for #name {
63 fn custom_parse(input: &str) -> anyhow::Result<Self> {
64 serde_json::from_str(input).map_err(|e| e.into())
65 }
66 }
67
68 impl ToString for #name {
69 fn to_string(&self) -> String {
70 serde_json::to_string(self).unwrap()
71 }
72 }
73 };
74
75 TokenStream::from(output)
76 } else {
77 panic!("Only structs are supported")
78 }
79}