sea_query_derive/iden/
iden_static.rs

1use super::*;
2
3pub fn expand(input: DeriveInput) -> TokenStream {
4    let DeriveInput {
5        ident, data, attrs, ..
6    } = input;
7
8    let sea_query_path = sea_query_path();
9
10    let table_name = match get_table_name(&ident, attrs) {
11        Ok(v) => v,
12        Err(e) => return e.to_compile_error().into(),
13    };
14
15    // Currently we only support enums and unit structs
16    let variants =
17        match data {
18            syn::Data::Enum(DataEnum { variants, .. }) => variants,
19            syn::Data::Struct(DataStruct {
20                fields: Fields::Unit,
21                ..
22            }) => {
23                let impl_iden = impl_iden_for_unit_struct(&ident, &table_name);
24
25                return quote! {
26                    #impl_iden
27
28                    impl #sea_query_path::IdenStatic for #ident {
29                        fn as_str(&self) -> &'static str {
30                            #table_name
31                        }
32                    }
33
34                    impl std::convert::AsRef<str> for #ident {
35                        fn as_ref(&self) -> &str {
36                            self.as_str()
37                        }
38                    }
39                }
40                .into();
41            }
42            _ => return quote_spanned! {
43                ident.span() => compile_error!("you can only derive Iden on enums or unit structs");
44            }
45            .into(),
46        };
47
48    if variants.is_empty() {
49        return TokenStream::new();
50    }
51
52    let impl_iden = impl_iden_for_enum(&ident, &table_name, variants.iter());
53
54    let match_arms = match variants
55        .iter()
56        .map(|v| (table_name.as_str(), v))
57        .map(IdenVariant::<DeriveIdenStatic>::try_from)
58        .collect::<syn::Result<Vec<_>>>()
59    {
60        Ok(v) => v,
61        Err(e) => return e.to_compile_error().into(),
62    };
63
64    let output = quote! {
65        #impl_iden
66
67        impl #sea_query_path::IdenStatic for #ident {
68            fn as_str(&self) -> &'static str {
69                match self {
70                    #(#match_arms),*
71                }
72            }
73        }
74
75        impl std::convert::AsRef<str> for #ident {
76            fn as_ref(&self) -> &'static str {
77                self.as_str()
78            }
79        }
80    };
81
82    output.into()
83}