|
@@ -4,7 +4,7 @@ use quote::{quote,format_ident};
|
|
|
|
|
|
use convert_case::{Case, Casing};
|
|
use convert_case::{Case, Casing};
|
|
|
|
|
|
-/// Turns a serializable/deserializable struct into a microrm model entity.
|
|
|
|
|
|
+/// Turns a serializable/deserializable struct into a microrm entity model.
|
|
/// There are two important visible effects:
|
|
/// There are two important visible effects:
|
|
/// - Provides an implementation of `microrm::model::Entity`
|
|
/// - Provides an implementation of `microrm::model::Entity`
|
|
/// - Defines a <struct-name>Columns enum
|
|
/// - Defines a <struct-name>Columns enum
|
|
@@ -12,10 +12,34 @@ use convert_case::{Case, Casing};
|
|
/// Note that names are converted from CamelCase to snake_case and vice versa
|
|
/// Note that names are converted from CamelCase to snake_case and vice versa
|
|
/// where applicable, so a struct named `TestModel` is given a table name `test_model`
|
|
/// where applicable, so a struct named `TestModel` is given a table name `test_model`
|
|
/// and a struct field named `field_name` is given a variant name of `FieldName`.
|
|
/// and a struct field named `field_name` is given a variant name of `FieldName`.
|
|
-#[proc_macro_derive(Entity, attributes(microrm))]
|
|
|
|
|
|
+///
|
|
|
|
+/// The #[microrm...] attributes can be used to control the derivation somewhat.
|
|
|
|
+/// The following are understood:
|
|
|
|
+/// - #[microrm_internal]: this is internal to the microrm crate (of extremely limited usefulness
|
|
|
|
+/// outside the microrm library)
|
|
|
|
+#[proc_macro_derive(Entity, attributes(microrm_internal))]
|
|
pub fn derive_entity(tokens: TokenStream) -> TokenStream {
|
|
pub fn derive_entity(tokens: TokenStream) -> TokenStream {
|
|
let input = parse_macro_input!(tokens as DeriveInput);
|
|
let input = parse_macro_input!(tokens as DeriveInput);
|
|
|
|
|
|
|
|
+ let mut microrm_ref = quote!{ ::microrm };
|
|
|
|
+
|
|
|
|
+ // parse attributes
|
|
|
|
+ for attr in input.attrs {
|
|
|
|
+ if attr.path.segments.len() == 0 { continue }
|
|
|
|
+
|
|
|
|
+ if attr.tokens.is_empty() {
|
|
|
|
+ if attr.path.segments.last().unwrap().ident == "microrm_internal" {
|
|
|
|
+ microrm_ref = quote!{ crate };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ let body : Result<syn::Expr,_> = syn::parse2(attr.tokens);
|
|
|
|
+ println!("body: {:?}", body);
|
|
|
|
+ if body.is_err() { continue }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
let struct_name = &input.ident;
|
|
let struct_name = &input.ident;
|
|
let enum_name = format_ident!("{}Columns", &input.ident);
|
|
let enum_name = format_ident!("{}Columns", &input.ident);
|
|
|
|
|
|
@@ -48,17 +72,16 @@ pub fn derive_entity(tokens: TokenStream) -> TokenStream {
|
|
let field_count = fields.named.iter().count();
|
|
let field_count = fields.named.iter().count();
|
|
|
|
|
|
let ret = quote!{
|
|
let ret = quote!{
|
|
-
|
|
|
|
#[derive(Clone,Copy)]
|
|
#[derive(Clone,Copy)]
|
|
pub enum #enum_name {
|
|
pub enum #enum_name {
|
|
#variants
|
|
#variants
|
|
}
|
|
}
|
|
|
|
|
|
- impl ::microrm::model::EntityColumns for #enum_name {
|
|
|
|
|
|
+ impl #microrm_ref::model::EntityColumns for #enum_name {
|
|
type Entity = #struct_name;
|
|
type Entity = #struct_name;
|
|
}
|
|
}
|
|
|
|
|
|
- impl ::microrm::model::Entity for #struct_name {
|
|
|
|
|
|
+ impl #microrm_ref::model::Entity for #struct_name {
|
|
fn table_name() -> &'static str { #table_name }
|
|
fn table_name() -> &'static str { #table_name }
|
|
type Column = #enum_name;
|
|
type Column = #enum_name;
|
|
fn column_count() -> usize {
|
|
fn column_count() -> usize {
|
|
@@ -72,7 +95,7 @@ pub fn derive_entity(tokens: TokenStream) -> TokenStream {
|
|
#field_names
|
|
#field_names
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- fn values(&self) -> Vec<&dyn ::microrm::re_export::rusqlite::ToSql> {
|
|
|
|
|
|
+ fn values(&self) -> Vec<&dyn #microrm_ref ::re_export::rusqlite::ToSql> {
|
|
vec![ #value_references ]
|
|
vec![ #value_references ]
|
|
}
|
|
}
|
|
}
|
|
}
|