diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parse_assoc_type.rs | 27 | ||||
| -rw-r--r-- | src/parse_trait_sig.rs | 6 | ||||
| -rw-r--r-- | src/transform.rs | 11 | 
3 files changed, 33 insertions, 11 deletions
| diff --git a/src/parse_assoc_type.rs b/src/parse_assoc_type.rs index 37fd78c..a255455 100644 --- a/src/parse_assoc_type.rs +++ b/src/parse_assoc_type.rs @@ -2,6 +2,7 @@ use proc_macro2::Span;  use syn::spanned::Spanned;  use syn::{GenericArgument, Ident, PathArguments, PathSegment, TraitItemType, Type}; +use crate::parse_trait_sig::TypeTransform;  use crate::syn_utils::{find_in_type, trait_bounds};  use crate::AssocTypeMatcher; @@ -12,9 +13,27 @@ pub enum AssocTypeParseError {      NoIntoBound,  } +pub enum DestType<'a> { +    Into(&'a Type), +} + +impl DestType<'_> { +    pub fn get_dest(&self) -> Type { +        match self { +            DestType::Into(ty) => (*ty).clone(), +        } +    } + +    pub fn type_transformation(&self) -> TypeTransform { +        match self { +            DestType::Into(_) => TypeTransform::Into, +        } +    } +} +  pub fn parse_assoc_type(      assoc_type: &TraitItemType, -) -> Result<(&Ident, &Type), (Span, AssocTypeParseError)> { +) -> Result<(&Ident, DestType), (Span, AssocTypeParseError)> {      for bound in trait_bounds(&assoc_type.bounds) {          if let PathSegment {              ident, @@ -36,7 +55,7 @@ pub fn parse_assoc_type(                          ));                      } -                    return Ok((&assoc_type.ident, into_type)); +                    return Ok((&assoc_type.ident, DestType::Into(into_type)));                  }              }          } @@ -49,7 +68,7 @@ mod tests {      use quote::quote;      use syn::{TraitItemType, Type}; -    use crate::parse_assoc_type::{parse_assoc_type, AssocTypeParseError}; +    use crate::parse_assoc_type::{parse_assoc_type, AssocTypeParseError, DestType};      #[test]      fn ok() { @@ -60,7 +79,7 @@ mod tests {          assert!(matches!(              parse_assoc_type(&type1), -            Ok((id, Type::Path(path))) +            Ok((id, DestType::Into(Type::Path(path))))              if id == "A" && path.path.is_ident("String")          ));      } diff --git a/src/parse_trait_sig.rs b/src/parse_trait_sig.rs index 5b1f91a..b7b7b3f 100644 --- a/src/parse_trait_sig.rs +++ b/src/parse_trait_sig.rs @@ -141,6 +141,7 @@ mod tests {      use syn::{TraitItemMethod, Type};      use crate::{ +        parse_assoc_type::DestType,          parse_trait_sig::{              parse_trait_signature, MethodParseError, SignatureChanges, TypeTransform,          }, @@ -172,8 +173,9 @@ mod tests {          let mut assoc_type_map = AssocTypeConversions::default();          let ident = format_ident!("A"); -        let dest = Type::Verbatim(quote! {Example}); -        assoc_type_map.0.insert(ident, &dest); +        let dest_inner = Type::Verbatim(quote! {Example}); +        let dest = DestType::Into(&dest_inner); +        assoc_type_map.0.insert(ident, dest);          assert!(matches!(              parse_trait_signature(&mut type1.sig, &assoc_type_map), diff --git a/src/transform.rs b/src/transform.rs index ec2f3a6..39b32cc 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -6,13 +6,14 @@ use syn::{  };  use crate::{ +    parse_assoc_type::DestType,      parse_trait_sig::{MethodParseError, TypeTransform},      syn_utils::{find_in_path, find_in_type},      As, AssocTypeMatcher,  };  #[derive(Default)] -pub struct AssocTypeConversions<'a>(pub HashMap<Ident, &'a Type>); +pub struct AssocTypeConversions<'a>(pub HashMap<Ident, DestType<'a>>);  pub enum TransformError {      UnconvertibleAssocType(Span), @@ -34,12 +35,12 @@ impl AssocTypeConversions<'_> {              if ident == "Self" && path.segments.len() == 2 {                  let ident = &path.segments.last().unwrap().ident; -                *type_ = (*self +                let dest_type = self                      .0                      .get(ident) -                    .ok_or_else(|| TransformError::UnconvertibleAssocType(ident.span()))?) -                .clone(); -                return Ok(TypeTransform::Into); +                    .ok_or_else(|| TransformError::UnconvertibleAssocType(ident.span()))?; +                *type_ = dest_type.get_dest(); +                return Ok(dest_type.type_transformation());              } else if ident == "Option" && path.segments.len() == 1 {                  let first_seg = path.segments.first_mut().unwrap(); | 
