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}