aboutsummaryrefslogtreecommitdiff
path: root/src/transform.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/transform.rs')
-rw-r--r--src/transform.rs46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/transform.rs b/src/transform.rs
index b13b7cf..fff9c6c 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -1,9 +1,10 @@
use std::collections::HashMap;
use proc_macro2::Span;
+use quote::quote;
use syn::{
spanned::Spanned, GenericArgument, Generics, Ident, PathArguments, TraitBound, Type,
- TypeParamBound, TypePath, WherePredicate,
+ TypeParamBound, TypePath, TypeReference, TypeTraitObject, WherePredicate,
};
use crate::{
@@ -28,12 +29,49 @@ impl AssocTypeConversions<'_> {
None => return Ok(TypeTransform::NoOp),
};
+ if let Type::Reference(TypeReference {
+ lifetime: None,
+ mutability: Some(_),
+ elem,
+ ..
+ }) = type_
+ {
+ if let Type::TraitObject(TypeTraitObject {
+ dyn_token: Some(_),
+ bounds,
+ }) = elem.as_mut()
+ {
+ if bounds.len() == 1 {
+ if let TypeParamBound::Trait(bound) = bounds.first_mut().unwrap() {
+ if bound.path.segments.len() == 1 {
+ let first = bound.path.segments.first_mut().unwrap();
+ if first.ident == "Iterator" {
+ if let PathArguments::AngleBracketed(args) = &mut first.arguments {
+ if args.args.len() == 1 {
+ if let GenericArgument::Binding(binding) =
+ args.args.first_mut().unwrap()
+ {
+ if binding.ident == "Item"
+ && iter_type(&binding.ty).any(match_assoc_type)
+ {
+ let inner =
+ self.parse_type_path(&mut binding.ty)?;
+ *type_ = Type::Verbatim(quote! {Box<#elem + '_>});
+ return Ok(TypeTransform::Iterator(inner.into()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
if let Type::Path(TypePath { path, qself: None }) = type_ {
let ident = &path.segments.first().unwrap().ident;
- // TODO: support &mut dyn Iterator<Item = Self::A>
- // conversion to Box<dyn Iterator<Item = Whatever>> via .map(Into::into)
-
if ident == "Self" && path.segments.len() == 2 {
let ident = &path.segments.last().unwrap().ident;
let dest_type = self