musty_proc_macro/lib.rs
1use darling::{FromDeriveInput, FromMeta};
2use model::meta_model::{MetaModelAttr, MetaModelDerive};
3use proc_macro::{self, TokenStream};
4use proc_macro_error::proc_macro_error;
5use syn::{parse_macro_input, AttributeArgs, DeriveInput};
6
7mod model;
8mod util;
9
10/// Reconstructs model struct and derives `Model` (and database-specific model traits).
11///
12/// Usage:
13/// ```
14/// use musty::prelude::*;
15/// #[model(mongo(collection = "users"))]
16/// struct Users {
17/// #[musty(id)] // this is optional, the macro looks for a field with this attribute or named "id"
18/// id: ObjectId,
19/// name: String
20/// }
21/// ```
22///
23/// this derives `serde::Serialize`, `serde::Deserialize`, `Debug`, and adds the necessary serde attributes to the struct and id field.
24/// the id field is also changed to be of type `musty::prelude::Id<Self, I>`, where `I` is the type of your `id` field (in this case: `ObjectId`)
25#[proc_macro_attribute]
26#[proc_macro_error]
27pub fn model(args: TokenStream, stream: TokenStream) -> TokenStream {
28 let arg_model = match MetaModelAttr::from_list(&parse_macro_input!(args as AttributeArgs)) {
29 Ok(m) => m,
30 Err(e) => return TokenStream::from(e.write_errors()),
31 };
32
33 let meta_model =
34 match MetaModelDerive::from_derive_input(&parse_macro_input!(stream as DeriveInput)) {
35 Ok(m) => m,
36 Err(e) => return TokenStream::from(e.write_errors()),
37 };
38
39 meta_model.expand(arg_model)
40}