aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-19 10:51:57 +0100
committerMartin Fischer <martin@push-f.com>2021-11-19 10:51:57 +0100
commitfb4ba51a742cb7b61c2e0c3059aba9c689b411e8 (patch)
tree426116acc038cef761b2108ae98ba51e4855e8ba
parentd8a313dd422c78fb018cfe4249b526fe3e9dc851 (diff)
refactor: make destination type mechanism extensible
-rw-r--r--src/parse_assoc_type.rs27
-rw-r--r--src/parse_trait_sig.rs6
-rw-r--r--src/transform.rs11
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();