serde_query_derive/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use proc_macro_error::{emit_error, proc_macro_error};
5use quote::quote;
6use serde_query_core::DeriveTarget;
7use syn::{parse_macro_input, DeriveInput};
8
9/// Generate a minimal, non-functioning Deserialize(Query) implementation on errors
10fn set_dummy(input: &DeriveInput, target: DeriveTarget) {
11    let name = &input.ident;
12    let generics = &input.generics;
13
14    match target {
15        DeriveTarget::Deserialize => {
16            proc_macro_error::set_dummy(quote! {
17                const _: () = {
18                    impl<'de> serde_query::__priv::serde::de::Deserialize<'de> for #name #generics {
19                        fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
20                        where
21                            D: serde_query::__priv::serde::de::Deserializer<'de>
22                        {
23                            unimplemented!()
24                        }
25                    }
26                };
27            });
28        }
29        DeriveTarget::DeserializeQuery => {
30            proc_macro_error::set_dummy(quote! {
31                const _: () = {
32                    struct __QueryWrapper;
33
34                    impl<'de> serde_query::__priv::serde::de::Deserialize<'de> for __QueryWrapper {
35                        fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
36                        where
37                            D: serde_query::__priv::serde::de::Deserializer<'de>
38                        {
39                            todo!()
40                        }
41                    }
42
43                    impl core::convert::From<__QueryWrapper> for #name #generics {
44                        fn from(val: __QueryWrapper) -> Self {
45                            todo!()
46                        }
47                    }
48
49                    impl core::ops::Deref for __QueryWrapper {
50                        type Target = #name;
51
52                        fn deref(&self) -> &Self::Target {
53                            todo!()
54                        }
55                    }
56
57                    impl core::ops::DerefMut for __QueryWrapper {
58                        fn deref_mut(&mut self) -> &mut Self::Target {
59                            todo!()
60                        }
61                    }
62
63                    impl<'de> serde_query::DeserializeQuery<'de> for #name #generics {
64                        type Query = __QueryWrapper;
65                    }
66                };
67            });
68        }
69    }
70}
71
72fn generate_derive(input: TokenStream, target: DeriveTarget) -> TokenStream {
73    let input = parse_macro_input!(input as DeriveInput);
74
75    set_dummy(&input, target);
76
77    if !input.generics.params.is_empty() {
78        emit_error!(input.generics, "generic arguments are not supported");
79        return TokenStream::new();
80    }
81
82    match serde_query_core::generate_derive(input, target) {
83        Ok(stream) => stream.into(),
84        Err(diagnostics) => {
85            for diagnostic in diagnostics {
86                diagnostic.emit();
87            }
88            TokenStream::new()
89        }
90    }
91}
92
93#[proc_macro_error]
94#[proc_macro_derive(DeserializeQuery, attributes(query))]
95pub fn derive_deserialize_query(input: TokenStream) -> TokenStream {
96    generate_derive(input, DeriveTarget::DeserializeQuery)
97}
98
99#[proc_macro_error]
100#[proc_macro_derive(Deserialize, attributes(query))]
101pub fn derive_deserialize(input: TokenStream) -> TokenStream {
102    generate_derive(input, DeriveTarget::Deserialize)
103}