1mod node;
2mod parse_input;
3mod parse_query;
4mod query;
5
6#[cfg(test)]
7mod tests;
8
9use node::Node;
10use parse_input::parse_input;
11use proc_macro2::{Span, TokenStream};
12use proc_macro_error::Diagnostic;
13use syn::DeriveInput;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum DeriveTarget {
17 Deserialize,
18 DeserializeQuery,
19}
20
21pub fn generate_derive(
22 mut input: DeriveInput,
23 target: DeriveTarget,
24) -> Result<TokenStream, Vec<Diagnostic>> {
25 let parse_input_result = parse_input(&mut input);
26 if !parse_input_result.diagnostics.is_empty() {
27 return Err(parse_input_result.diagnostics);
28 }
29
30 let name = &input.ident;
31 let node = Node::from_queries(parse_input_result.queries.into_iter())?;
32 let mut stream = node.generate().map_err(|diagnostic| vec![diagnostic])?;
33
34 match target {
36 DeriveTarget::DeserializeQuery => {
38 let wrapper_ty = syn::Ident::new("__QueryWrapper", Span::call_site());
39
40 let vis = input.vis;
43
44 let deserialize_impl = node.generate_deserialize(
45 name,
46 &wrapper_ty,
47 |value| quote::quote!(#wrapper_ty(#value)),
48 );
49
50 stream.extend(quote::quote! {
51 #[repr(transparent)]
52 #vis struct #wrapper_ty (#name);
53
54 #deserialize_impl
55
56 impl core::convert::From<#wrapper_ty> for #name {
57 fn from(val: #wrapper_ty) -> Self {
58 val.0
59 }
60 }
61
62 impl core::ops::Deref for #wrapper_ty {
63 type Target = #name;
64
65 fn deref(&self) -> &Self::Target {
66 &self.0
67 }
68 }
69
70 impl core::ops::DerefMut for #wrapper_ty {
71 fn deref_mut(&mut self) -> &mut Self::Target {
72 &mut self.0
73 }
74 }
75 });
76
77 stream.extend(quote::quote! {
78 impl<'de> serde_query::DeserializeQuery<'de> for #name {
79 type Query = #wrapper_ty;
80 }
81 });
82 }
83 DeriveTarget::Deserialize => {
84 let deserialize_impl = node.generate_deserialize(name, name, |value| value);
85 stream.extend(deserialize_impl);
86 }
87 }
88
89 Ok(quote::quote! {
91 const _: () = {
92 #stream
93 };
94 })
95}