diff options
-rw-r--r-- | examples/tutorial02/polls/models.rs | 2 | ||||
-rw-r--r-- | tests/tutorial/mod.rs | 1 | ||||
-rw-r--r-- | tosin-macros/src/lib.rs | 82 |
3 files changed, 63 insertions, 22 deletions
diff --git a/examples/tutorial02/polls/models.rs b/examples/tutorial02/polls/models.rs index d62f219..c9de156 100644 --- a/examples/tutorial02/polls/models.rs +++ b/examples/tutorial02/polls/models.rs @@ -6,7 +6,7 @@ pub struct Question { #[model(max_length=200)] question_text: String, /// date published - pub_date: time::PrimitiveDateTime, + pub_date: chrono::NaiveDateTime, } #[derive(Model, PartialEq, Debug)] diff --git a/tests/tutorial/mod.rs b/tests/tutorial/mod.rs index 8a602a3..5d969cf 100644 --- a/tests/tutorial/mod.rs +++ b/tests/tutorial/mod.rs @@ -254,7 +254,6 @@ edition = "2018" [dependencies] chrono = "0.4" diesel = { version = "1.4.4", features = ["sqlite"] } -time = "0.2.27" tosin = { path = "../../.." } "#, ) diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs index 131888c..15a0266 100644 --- a/tosin-macros/src/lib.rs +++ b/tosin-macros/src/lib.rs @@ -31,7 +31,7 @@ struct FieldsInfo<T: quote::ToTokens> { } impl<T: quote::ToTokens> std::iter::FromIterator<FieldInfo<T>> for FieldsInfo<T> { - fn from_iter<I: IntoIterator<Item=FieldInfo<T>>>(iter: I) -> Self { + fn from_iter<I: IntoIterator<Item = FieldInfo<T>>>(iter: I) -> Self { let mut result = Self { tosin_fields: vec![], diesel_columns: vec![], @@ -52,9 +52,17 @@ fn to_field_spec(field: &syn::Field) -> FieldInfo<impl quote::ToTokens> { } let field_name = &field.ident; let field_type = &field.ty; - let model_options: HashMap<syn::Path, syn::Lit> = field.attrs.iter() + let model_options: HashMap<syn::Path, syn::Lit> = field + .attrs + .iter() .filter_map(|attr| attr.parse_meta().ok()) - .filter_map(|meta| if let syn::Meta::List(meta) = meta { Some(meta) } else { None }) + .filter_map(|meta| { + if let syn::Meta::List(meta) = meta { + Some(meta) + } else { + None + } + }) .filter(|meta| meta.path.get_ident().map_or(false, |path| path == "model")) .flat_map(|model| { model.nested.into_iter().filter_map(|item| { @@ -87,27 +95,28 @@ fn to_field_spec(field: &syn::Field) -> FieldInfo<impl quote::ToTokens> { diesel_type: quote! { ::tosin::db::sql_types::Integer }, } } else if field_type == &parse_type("String") { - let max_length = model_options.iter() + let max_length = model_options + .iter() .find(|(name, _value)| name.get_ident().map_or(false, |path| path == "max_length")) .map(|(_name, value)| value); if let Some(max_length) = max_length { FieldInfo { tosin_field: quote! { ::tosin::db::models::Field::CharField { name: stringify!(#field_name), max_length: Some(#max_length) } }, diesel_column: quote! { #field_name -> Text }, - diesel_type: quote! { ::tosin::db::sql_types::Text } + diesel_type: quote! { ::tosin::db::sql_types::Text }, } } else { FieldInfo { tosin_field: quote! { ::tosin::db::models::Field::CharField { name: stringify!(#field_name), max_length: None } }, diesel_column: quote! { #field_name -> Text }, - diesel_type: quote! { ::tosin::db::sql_types::Text } + diesel_type: quote! { ::tosin::db::sql_types::Text }, } } - } else if field_type == &parse_type("time::PrimitiveDateTime") { + } else if field_type == &parse_type("chrono::NaiveDateTime") { FieldInfo { tosin_field: quote! { ::tosin::db::models::Field::DateTimeField { name: stringify!(#field_name) } }, diesel_column: quote! { #field_name -> Timestamp }, - diesel_type: quote! { ::tosin::db::sql_types::Timestamp } + diesel_type: quote! { ::tosin::db::sql_types::Timestamp }, } } else { use quote::ToTokens; @@ -124,7 +133,11 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { panic!("not on a struct"); }; let real_types: Vec<_> = ast_data.fields.iter().map(|field| &field.ty).collect(); - let FieldsInfo { tosin_fields, diesel_columns, diesel_types } = ast_data.fields.iter().map(to_field_spec).collect(); + let FieldsInfo { + tosin_fields, + diesel_columns, + diesel_types, + } = ast_data.fields.iter().map(to_field_spec).collect(); let gen = quote! { impl #name { pub const META: ::tosin::db::models::ModelMeta = ::tosin::db::models::ModelMeta { @@ -163,7 +176,8 @@ pub fn gather_migrations(_input: TokenStream) -> TokenStream { } let migrations_dir = call_site_path.parent().unwrap(); - let migrations: Vec<syn::Ident> = migrations_dir.read_dir() + let migrations: Vec<syn::Ident> = migrations_dir + .read_dir() .unwrap() .map(Result::unwrap) .map(|x| x.path().file_stem().unwrap().to_string_lossy().into_owned()) @@ -192,18 +206,46 @@ pub fn gather_models(_input: TokenStream) -> TokenStream { } let call_site_ast = syn::parse_file(&fs::read_to_string(call_site_path).unwrap()).unwrap(); - let models = call_site_ast.items.iter() - .filter_map(|item| if let syn::Item::Struct(item) = item { Some(item) } else { None }) - .filter(|item| item.attrs.iter().any(|attr| { - let attr = if let Ok(syn::Meta::List(attr)) = attr.parse_meta() { attr } else { return false; }; - if attr.path.get_ident().map_or(false, |hopefully_derive| hopefully_derive == "derive") { - let mut derived = attr.nested.iter() - .filter_map(|derived| if let syn::NestedMeta::Meta(derived) = derived { Some(derived) } else { None }); - derived.any(|derived| derived.path().get_ident().map_or(false, |hopefully_model| hopefully_model == "Model")) + let models = call_site_ast + .items + .iter() + .filter_map(|item| { + if let syn::Item::Struct(item) = item { + Some(item) } else { - false + None } - })) + }) + .filter(|item| { + item.attrs.iter().any(|attr| { + let attr = if let Ok(syn::Meta::List(attr)) = attr.parse_meta() { + attr + } else { + return false; + }; + if attr + .path + .get_ident() + .map_or(false, |hopefully_derive| hopefully_derive == "derive") + { + let mut derived = attr.nested.iter().filter_map(|derived| { + if let syn::NestedMeta::Meta(derived) = derived { + Some(derived) + } else { + None + } + }); + derived.any(|derived| { + derived + .path() + .get_ident() + .map_or(false, |hopefully_model| hopefully_model == "Model") + }) + } else { + false + } + }) + }) .map(|item| &item.ident); let gen = quote! { |