diff options
Diffstat (limited to 'src/parse_assoc_type.rs')
-rw-r--r-- | src/parse_assoc_type.rs | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/src/parse_assoc_type.rs b/src/parse_assoc_type.rs index a255455..7efc7da 100644 --- a/src/parse_assoc_type.rs +++ b/src/parse_assoc_type.rs @@ -1,9 +1,10 @@ use proc_macro2::Span; +use quote::{quote, ToTokens}; use syn::spanned::Spanned; -use syn::{GenericArgument, Ident, PathArguments, PathSegment, TraitItemType, Type}; +use syn::{GenericArgument, Ident, Path, PathArguments, PathSegment, TraitItemType, Type}; use crate::parse_trait_sig::TypeTransform; -use crate::syn_utils::{find_in_type, trait_bounds}; +use crate::syn_utils::{find_in_type, lifetime_bounds, trait_bounds}; use crate::AssocTypeMatcher; #[derive(Debug)] @@ -13,20 +14,39 @@ pub enum AssocTypeParseError { NoIntoBound, } +#[derive(Debug, Clone)] +pub struct BoxType { + trait_name: Path, + placeholder_lifetime: bool, +} + +impl ToTokens for BoxType { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let path = &self.trait_name; + match self.placeholder_lifetime { + true => tokens.extend(quote! {Box<dyn #path + '_>}), + false => tokens.extend(quote! {Box<dyn #path>}), + } + } +} + pub enum DestType<'a> { Into(&'a Type), + Box(BoxType), } impl DestType<'_> { pub fn get_dest(&self) -> Type { match self { DestType::Into(ty) => (*ty).clone(), + DestType::Box(b) => Type::Verbatim(quote!(#b)), } } pub fn type_transformation(&self) -> TypeTransform { match self { DestType::Into(_) => TypeTransform::Into, + DestType::Box(b) => TypeTransform::Box(b.clone()), } } } @@ -34,7 +54,7 @@ impl DestType<'_> { pub fn parse_assoc_type( assoc_type: &TraitItemType, ) -> Result<(&Ident, DestType), (Span, AssocTypeParseError)> { - for bound in trait_bounds(&assoc_type.bounds) { + if let Some(bound) = trait_bounds(&assoc_type.bounds).next() { if let PathSegment { ident, arguments: PathArguments::AngleBracketed(args), @@ -59,6 +79,14 @@ pub fn parse_assoc_type( } } } + return Ok(( + &assoc_type.ident, + DestType::Box(BoxType { + trait_name: bound.path.clone(), + placeholder_lifetime: !lifetime_bounds(&assoc_type.bounds) + .any(|l| l.ident == "static"), + }), + )); } Err((assoc_type.span(), AssocTypeParseError::NoIntoBound)) } |