From 2d1a6b2d432408d74eb57e0bda3f7434617e1070 Mon Sep 17 00:00:00 2001 From: HampusM Date: Wed, 20 Jul 2022 14:29:45 +0200 Subject: refactor: reorganize folder hierarchy --- macros/src/factory_type_alias.rs | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 macros/src/factory_type_alias.rs (limited to 'macros/src/factory_type_alias.rs') diff --git a/macros/src/factory_type_alias.rs b/macros/src/factory_type_alias.rs new file mode 100644 index 0000000..8ea7baa --- /dev/null +++ b/macros/src/factory_type_alias.rs @@ -0,0 +1,84 @@ +use syn::parse::{Parse, ParseStream}; +use syn::{GenericArgument, ItemType, Path, Type, TypeParamBound, TypeTuple}; + +pub struct FactoryTypeAlias +{ + pub type_alias: ItemType, + pub factory_interface: Path, + pub arg_types: TypeTuple, + 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::() { + Ok(type_alias) => Ok(type_alias), + 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" + ))), + }?; + + Ok(Self { + type_alias: type_alias.clone(), + factory_interface: bound_path.clone(), + arg_types: arg_types.clone(), + return_type: return_type.clone(), + }) + } +} -- cgit v1.2.3-18-g5258