diff options
Diffstat (limited to 'tosin-macros/src')
-rw-r--r-- | tosin-macros/src/lib.rs | 82 |
1 files changed, 62 insertions, 20 deletions
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! { |