diff --git a/native_db_macro/src/model_attributes.rs b/native_db_macro/src/model_attributes.rs index a4124ae..9859bbf 100644 --- a/native_db_macro/src/model_attributes.rs +++ b/native_db_macro/src/model_attributes.rs @@ -5,13 +5,14 @@ use quote::ToTokens; use std::collections::HashSet; use syn::meta::ParseNestedMeta; use syn::parse::Result; -use syn::Field; +use syn::{Field, LitBool}; #[derive(Clone)] pub(crate) struct ModelAttributes { pub(crate) struct_name: StructName, pub(crate) primary_key: Option>, pub(crate) secondary_keys: HashSet>, + pub(crate) do_export_keys: Option, } impl ModelAttributes { @@ -73,6 +74,8 @@ impl ModelAttributes { } self.secondary_keys.insert(key); + } else if meta.path.is_ident("export_keys") { + self.do_export_keys = Some(meta.value()?.parse()?); } else { panic!( "Unknown attribute: {}", diff --git a/native_db_macro/src/model_native_db.rs b/native_db_macro/src/model_native_db.rs index 26b008d..885c913 100644 --- a/native_db_macro/src/model_native_db.rs +++ b/native_db_macro/src/model_native_db.rs @@ -116,6 +116,21 @@ impl ModelNativeDB { Ident::new(&format!("{}Key", struct_name), Span::call_site().into()) } + pub(crate) fn keys_enum_visibility(&self) -> proc_macro2::TokenStream { + let do_export = match &self.attrs.do_export_keys { + Some(do_export_keys) => do_export_keys.value, + None => false, + }; + + let visibility = if do_export { + "" + } else { + "(crate)" + }; + + format!("pub{}", visibility).parse().unwrap() + } + pub(crate) fn secondary_keys_enum(&self) -> Vec { self.attrs .secondary_keys diff --git a/native_db_macro/src/native_db.rs b/native_db_macro/src/native_db.rs index c262f30..37b88a1 100644 --- a/native_db_macro/src/native_db.rs +++ b/native_db_macro/src/native_db.rs @@ -13,6 +13,7 @@ pub fn native_db(args: TokenStream, input: TokenStream) -> TokenStream { struct_name: struct_name.clone(), primary_key: None, secondary_keys: Default::default(), + do_export_keys: None, }; let model_attributes_parser = syn::meta::parser(|meta| attrs.parse(meta)); parse_macro_input!(args with model_attributes_parser); @@ -33,6 +34,7 @@ pub fn native_db(args: TokenStream, input: TokenStream) -> TokenStream { let native_db_gks = model_native_db.native_db_secondary_key(); let native_db_model = model_native_db.native_db_model(); + let keys_enum_visibility = model_native_db.keys_enum_visibility(); let keys_enum_name = model_native_db.keys_enum_name(); let keys_enum = model_native_db.secondary_keys_enum(); let keys_enum_database_key = model_native_db.keys_enum_database_key(); @@ -57,7 +59,7 @@ pub fn native_db(args: TokenStream, input: TokenStream) -> TokenStream { } #[allow(non_camel_case_types)] - pub(crate) enum #keys_enum_name { + #keys_enum_visibility enum #keys_enum_name { #(#keys_enum),* } diff --git a/src/lib.rs b/src/lib.rs index 18c9ec7..8ff39b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -391,6 +391,11 @@ doc_comment! { include_str!("../README.md") } -/// Macro which link [`native_model`](https://crates.io/crates/native_model) to the Native DB. See [`Builder.define`](struct.Builder.html#method.define) for more information. +/// Macro which link [`native_model`](https://crates.io/crates/native_model) to the Native DB. See +/// [`Builder.define`](struct.Builder.html#method.define) for more information. +/// +/// Optional parameter `export_keys` controls whether the model keys enum is visible outside of the +/// crate, default value is false with visibility limited to `pub(crate)`. Use +/// `#[native_db(export_keys = true)]` to make enum visible outside of crate (ie. `pub`). pub use native_db_macro::*; pub use serialization::*; diff --git a/tests/macro_def/export_keys_attribute.rs b/tests/macro_def/export_keys_attribute.rs new file mode 100644 index 0000000..27db9b8 --- /dev/null +++ b/tests/macro_def/export_keys_attribute.rs @@ -0,0 +1,27 @@ +use native_db::*; +use native_model::{native_model, Model}; +use serde::{Deserialize, Serialize}; + +// TODO somehow test visibility of keys enum from a sibling/child crate? + +/// Test struct to ensure `#[native_db(export_keys = true)]` compiles successfully +#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] +#[native_model(id = 1, version = 1)] +#[native_db(export_keys = true)] +struct Item { + #[primary_key] + id: u32, + #[secondary_key] + name: String, +} + +#[test] +fn test_insert_my_item() { + let item = Item { + id: 1, + name: "test".to_string(), + }; + + let key = item.native_db_primary_key(); + assert_eq!(key, 1_u32.to_key()); +} diff --git a/tests/macro_def/mod.rs b/tests/macro_def/mod.rs index b620a0a..b68db14 100644 --- a/tests/macro_def/mod.rs +++ b/tests/macro_def/mod.rs @@ -3,3 +3,4 @@ mod primary_key_attribute; mod secondary_key; mod secondary_key_attribute; mod secondary_key_mix; +mod export_keys_attribute;