Просмотр исходного кода

Add microrm_internal attribute to Entity derive macro.

Kestrel 2 лет назад
Родитель
Сommit
b359e49ac2
4 измененных файлов с 40 добавлено и 15 удалено
  1. 1 1
      microrm-macros/Cargo.toml
  2. 29 6
      microrm-macros/src/lib.rs
  3. 5 3
      microrm/src/lib.rs
  4. 5 5
      microrm/src/model/create.rs

+ 1 - 1
microrm-macros/Cargo.toml

@@ -10,7 +10,7 @@ proc-macro = true
 
 [dependencies]
 # proc_macro = "*"
-syn = { version = "1.0", features = ["derive"] }
+syn = { version = "1.0", features = ["derive", "extra-traits"] }
 quote = "1.0"
 convert_case = "0.5"
 proc-macro2 = "1.0"

+ 29 - 6
microrm-macros/src/lib.rs

@@ -4,7 +4,7 @@ use quote::{quote,format_ident};
 
 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:
 /// - Provides an implementation of `microrm::model::Entity`
 /// - 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
 /// 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`.
-#[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 {
     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 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 ret = quote!{
-
         #[derive(Clone,Copy)]
         pub enum #enum_name {
             #variants
         }
 
-        impl ::microrm::model::EntityColumns for #enum_name {
+        impl #microrm_ref::model::EntityColumns for #enum_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 }
             type Column = #enum_name;
             fn column_count() -> usize {
@@ -72,7 +95,7 @@ pub fn derive_entity(tokens: TokenStream) -> TokenStream {
                     #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 ]
             }
         }

+ 5 - 3
microrm/src/lib.rs

@@ -46,10 +46,13 @@ mod meta;
 
 pub use microrm_macros::Entity;
 
+// no need to show the re-exports in the documentation
+#[doc(hidden)]
 pub mod re_export {
     pub use rusqlite;
 }
 
+/// SQLite database connection
 pub struct DB {
     conn: rusqlite::Connection,
     schema_hash: String,
@@ -150,13 +153,13 @@ impl DB {
     }
 }
 
-/*
 #[cfg(test)]
 mod test {
     use super::DB;
 
     #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
-    struct S1 {
+    #[microrm_internal]
+    pub struct S1 {
         id: i32,
     }
 
@@ -169,4 +172,3 @@ mod test {
         let _db = DB::new_in_memory(simple_schema());
     }
 }
-*/

+ 5 - 5
microrm/src/model/create.rs

@@ -119,14 +119,15 @@ pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
     )
 }
 
-/*
 #[cfg(test)]
 mod test {
     #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
-    struct Empty {}
+    #[microrm_internal]
+    pub struct Empty {}
 
     #[derive(serde::Serialize, serde::Deserialize, crate::Entity)]
-    struct Single {
+    #[microrm_internal]
+    pub struct Single {
         e: i32,
     }
 
@@ -135,7 +136,7 @@ mod test {
         assert_eq!(
             super::sql_for::<Empty>(),
             (
-                r#"DROP TABLE IF EXISTS "empty"#.to_owned(),
+                r#"DROP TABLE IF EXISTS "empty""#.to_owned(),
                 r#"CREATE TABLE "empty" ()"#.to_owned()
             )
         );
@@ -148,4 +149,3 @@ mod test {
         );
     }
 }
-*/