1#[doc(hidden)]
17use proc_macro::TokenStream;
18mod column;
19pub(crate) mod column_meta;
20use column::collect_meta;
21use column_meta::COLUMN_META;
22
23#[doc(hidden)]
24use quote::quote;
25
26#[doc(hidden)]
27use syn::parse_macro_input;
28pub(crate) mod indexes;
29
30#[proc_macro_derive(
61 Column,
62 attributes(dropIndexes, singleIndex, compoundIndex, multikeyIndex)
63)]
64pub fn column_derive(input: TokenStream) -> TokenStream {
65 let st = syn::parse_macro_input!(input as syn::DeriveInput);
66 let drop_indexes = st
67 .attrs
68 .iter()
69 .find(|attr| attr.path().is_ident("dropIndexes"));
70 let mut drop = false;
71 if drop_indexes.is_some() {
72 drop = true;
73 }
74 collect_meta(&st, drop)
75 .unwrap_or_else(|e| e.to_compile_error())
76 .into()
77}
78
79#[proc_macro_attribute]
91pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream {
92 let st = parse_macro_input!(input as syn::ItemFn);
93 let mut res = proc_macro2::TokenStream::new();
94 res.extend(quote!(
95 #[derive(Debug, Clone)]
96 pub struct Server<T>(mongodb::Collection<T>);
97
98 unsafe impl<T> Send for Server<T> {}
99 unsafe impl<T> Sync for Server<T> {}
100
101 impl<T> std::ops::Deref for Server<T> {
102 type Target = mongodb::Collection<T>;
103
104 fn deref(&self) -> &Self::Target {
105 &self.0
106 }
107 }
108
109 impl<T> AsRef<mongodb::Collection<T>> for Server<T> {
110 fn as_ref(&self) -> &mongodb::Collection<T> {
111 &self.0
112 }
113 }
114
115 #[axum_mongodb::async_trait]
116 impl<T> axum_mongodb::NewWithDb for Server<T>
117 where
118 Self: axum_mongodb::CollectionInit,
119 {
120 async fn new(db: mongodb::Database) -> Self {
121 let type_name = std::any::type_name::<T>();
123 let mut collection_name = type_name.split("::").last().unwrap().to_lowercase();
124 collection_name.push('s');
125 let collection = db.collection::<T>(&collection_name);
126 let res = Self(collection);
127 res.init().await;
128 res
129 }
130 }
131
132 #[axum_mongodb::inject_meta]
133 pub struct Servers {}
134
135 #[axum_mongodb::async_trait]
136 impl<S> axum::extract::FromRequestParts<S> for crate::Servers
137 where
138 S: Send + Sync,
139 {
140 type Rejection = std::convert::Infallible;
141 async fn from_request_parts(
142 parts: &mut axum::http::request::Parts,
143 _state: &S,
144 ) -> Result<Self, Self::Rejection> {
145 let dbs = parts
146 .extensions
147 .get::<axum_mongodb::MongoDbServer<Self>>()
148 .expect("can not get MongoDbServer");
149 Ok(dbs.servers.clone())
150 }
151 }
152 #st
153 ));
154 res.into()
155}
156
157#[proc_macro_attribute]
159pub fn inject_meta(_attr: TokenStream, input: TokenStream) -> TokenStream {
160 let st = parse_macro_input!(input as syn::ItemStruct);
161 column::inject_meta(&st)
162 .unwrap_or_else(|e| e.to_compile_error())
163 .into()
164}
165
166#[proc_macro_attribute]
180pub fn inject(_attr: TokenStream, input: TokenStream) -> TokenStream {
181 let st = parse_macro_input!(input as syn::ItemFn);
182 column::inject(&st)
183 .unwrap_or_else(|e| e.to_compile_error())
184 .into()
185}