1use quote::ToTokens;
2use syn::DeriveInput;
3
4mod enumeration;
5mod error;
6mod filter;
7mod relation;
8mod root_query;
9
10#[proc_macro_derive(Filter, attributes(sea_orm))]
11pub fn derive_filter_fn(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
12 let DeriveInput {
13 ident, data, attrs, ..
14 } = syn::parse_macro_input!(input as syn::DeriveInput);
15
16 let item = match data {
17 syn::Data::Struct(item) => item,
18 _ => {
19 return quote::quote! {
20 compile_error!("Input not structure")
21 }
22 .into()
23 }
24 };
25
26 if ident.ne("Model") {
27 return quote::quote! {
28 compile_error!("Struct must be SeaOrm Model structure")
29 }
30 .into();
31 }
32
33 let attrs = filter::SeaOrm::from_attributes(&attrs).unwrap();
34
35 filter::filter_fn(item, attrs)
36 .unwrap_or_else(|err| {
37 let error = format!("{:?}", err);
38
39 quote::quote! {
40 compile_error!(#error)
41 }
42 })
43 .into()
44}
45
46#[proc_macro_derive(RelationsCompact, attributes(sea_orm))]
48pub fn derive_relations_compact_fn(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
49 let DeriveInput { ident, data, .. } = syn::parse_macro_input!(input as syn::DeriveInput);
50
51 let item = match data {
52 syn::Data::Enum(item) => item,
53 _ => return quote::quote! { compile_error!("Input not enumeration") }.into(),
54 };
55
56 if ident.ne("Relation") {
57 return quote::quote! {
58 compile_error!("Struct must be SeaOrm Relation enumeration")
59 }
60 .into();
61 }
62
63 let res = relation::compact_relation_fn(&item).unwrap_or_else(|err| {
64 let error = format!("{:?}", err);
65
66 quote::quote! {
67 compile_error!(#error)
68 }
69 });
70
71 res.into()
72}
73
74#[proc_macro_attribute]
75pub fn relation(
76 _attrs: proc_macro::TokenStream,
77 input: proc_macro::TokenStream,
78) -> proc_macro::TokenStream {
79 let implementation = syn::parse_macro_input!(input as syn::Item);
80
81 if !implementation
82 .to_token_stream()
83 .to_string()
84 .starts_with("impl RelationTrait")
85 {
86 return quote::quote! {
87 compile_error!("Macro should be applied on the implementation of RelationTrait trait")
88 }
89 .into();
90 }
91
92 let item = match implementation {
93 syn::Item::Impl(implementation) => implementation,
94 _ => return quote::quote! {
95 compile_error!("Macro should be applied on the implementation of RelationTrait trait")
96 }
97 .into(),
98 };
99
100 let res = relation::expanded_relation_fn(&item).unwrap_or_else(|err| {
101 let error = format!("{:?}", err);
102
103 quote::quote! {
104 compile_error!(#error)
105 }
106 });
107
108 res.into()
109}
110
111#[proc_macro_derive(QueryRoot, attributes(seaography))]
112pub fn derive_root_query_fn(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
113 let DeriveInput {
114 ident, data, attrs, ..
115 } = syn::parse_macro_input!(input as syn::DeriveInput);
116
117 match data {
118 syn::Data::Struct(_) => (),
119 _ => return quote::quote! { compile_error!("Input not structure") }.into(),
120 };
121
122 let attrs: Vec<root_query::Seaography> = attrs
123 .into_iter()
124 .map(|attribute| root_query::Seaography::from_attributes(&[attribute]).unwrap())
125 .collect();
126
127 let res = root_query::root_query_fn(&ident, &attrs).unwrap_or_else(|err| {
128 let error = format!("{:?}", err);
129
130 quote::quote! {
131 compile_error!(#error)
132 }
133 });
134
135 res.into()
136}
137
138#[proc_macro_derive(EnumFilter, attributes())]
139pub fn derive_enum_filter_fn(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
140 let DeriveInput { ident, data, .. } = syn::parse_macro_input!(input as syn::DeriveInput);
141
142 let _ = match data {
143 syn::Data::Enum(enumeration) => enumeration,
144 _ => return quote::quote! { compile_error!("Input not enumeration") }.into(),
145 };
146
147 enumeration::enum_filter_fn(ident).into()
148}