From c1e682c25c24be3174d44ceb95b0537c38299d0c Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 12 Sep 2022 20:22:13 +0200 Subject: feat!: allow factories access to DI container BREAKING CHANGE: Factory types should now be written with the Fn trait instead of the IFactory trait and the to_factory & to_default_factory methods of BindingBuilder now expect a function returning a factory function --- macros/src/factory_type_alias.rs | 75 +++++++--------------------------------- 1 file changed, 13 insertions(+), 62 deletions(-) (limited to 'macros/src/factory_type_alias.rs') diff --git a/macros/src/factory_type_alias.rs b/macros/src/factory_type_alias.rs index 8ea7baa..64afe57 100644 --- a/macros/src/factory_type_alias.rs +++ b/macros/src/factory_type_alias.rs @@ -1,17 +1,20 @@ +use quote::ToTokens; use syn::parse::{Parse, ParseStream}; -use syn::{GenericArgument, ItemType, Path, Type, TypeParamBound, TypeTuple}; +use syn::punctuated::Punctuated; +use syn::{parse, ItemType, Token, Type}; + +use crate::fn_trait::FnTrait; pub struct FactoryTypeAlias { pub type_alias: ItemType, - pub factory_interface: Path, - pub arg_types: TypeTuple, + pub factory_interface: FnTrait, + pub arg_types: Punctuated, pub return_type: Type, } impl Parse for FactoryTypeAlias { - #[allow(clippy::match_wildcard_for_single_variants)] fn parse(input: ParseStream) -> syn::Result { let type_alias = match input.parse::() { @@ -19,66 +22,14 @@ impl Parse for FactoryTypeAlias Err(_) => Err(input.error("Expected a type alias")), }?; - let aliased_trait = match &type_alias.ty.as_ref() { - Type::TraitObject(alias_type) => Ok(alias_type), - &_ => Err(input.error("Expected the aliased type to be a trait")), - }?; - - if aliased_trait.bounds.len() != 1 { - return Err(input.error("Expected the aliased trait to have a single bound.")); - } - - let bound_path = &match aliased_trait.bounds.first().unwrap() { - TypeParamBound::Trait(trait_bound) => Ok(trait_bound), - &_ => { - Err(input.error("Expected the bound of the aliased trait to be a trait")) - } - }? - .path; - - if bound_path.segments.is_empty() - || bound_path.segments.last().unwrap().ident != "IFactory" - { - return Err(input - .error("Expected the bound of the aliased trait to be 'dyn IFactory'")); - } - - let angle_bracketed_args = match &bound_path.segments.last().unwrap().arguments { - syn::PathArguments::AngleBracketed(angle_bracketed_args) => { - Ok(angle_bracketed_args) - } - &_ => { - Err(input.error("Expected angle bracketed arguments for 'dyn IFactory'")) - } - }?; - - let arg_types = match &angle_bracketed_args.args[0] { - GenericArgument::Type(arg_types_type) => match arg_types_type { - Type::Tuple(arg_types) => Ok(arg_types), - &_ => Err(input.error(concat!( - "Expected the first angle bracketed argument ", - "of 'dyn IFactory' to be a type tuple" - ))), - }, - &_ => Err(input.error(concat!( - "Expected the first angle bracketed argument ", - "of 'dyn IFactory' to be a type" - ))), - }?; - - let return_type = match &angle_bracketed_args.args[1] { - GenericArgument::Type(arg_type) => Ok(arg_type), - &_ => Err(input.error(concat!( - "Expected the second angle bracketed argument ", - "of 'dyn IFactory' to be a type" - ))), - }?; + let aliased_fn_trait = + parse::(type_alias.ty.as_ref().to_token_stream().into())?; Ok(Self { - type_alias: type_alias.clone(), - factory_interface: bound_path.clone(), - arg_types: arg_types.clone(), - return_type: return_type.clone(), + type_alias, + factory_interface: aliased_fn_trait.clone(), + arg_types: aliased_fn_trait.inputs, + return_type: aliased_fn_trait.output, }) } } -- cgit v1.2.3-18-g5258