diff options
| author | Martin Fischer <martin@push-f.com> | 2021-11-22 06:36:37 +0100 | 
|---|---|---|
| committer | Martin Fischer <martin@push-f.com> | 2021-11-22 07:45:30 +0100 | 
| commit | bacdafb4883d8f8ea06e498285c78f82de9a391b (patch) | |
| tree | 30f3f795e2b8c4895cea7e708ca4a1fe46eedd0c /src | |
| parent | a973a628ec051ab9483fde7d694bb261bb793178 (diff) | |
support Vec, VecDeque & LinkedList collections
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 6 | ||||
| -rw-r--r-- | src/parse_trait_sig.rs | 1 | ||||
| -rw-r--r-- | src/transform.rs | 21 | 
3 files changed, 27 insertions, 1 deletions
| @@ -409,7 +409,11 @@ impl TypeTransform {                      quote! {#arg.map_err(|x| #err_inner)}                  }              } -            _other => arg, +            TypeTransform::Collection(inner) => { +                let inner = inner.convert(quote!(x)); +                quote! {#arg.into_iter().map(|x| #inner).collect()} +            } +            TypeTransform::NoOp => arg,          }      }  } diff --git a/src/parse_trait_sig.rs b/src/parse_trait_sig.rs index ab2c437..c924a71 100644 --- a/src/parse_trait_sig.rs +++ b/src/parse_trait_sig.rs @@ -17,6 +17,7 @@ pub enum TypeTransform {      Into,      Box(BoxType),      Map(Box<TypeTransform>), +    Collection(Box<TypeTransform>),      Iterator(BoxType, Box<TypeTransform>),      Result(Box<TypeTransform>, Box<TypeTransform>),  } diff --git a/src/transform.rs b/src/transform.rs index e8481bb..3f1c313 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -22,6 +22,12 @@ pub enum TransformError {      AssocTypeInUnsupportedType(Span),  } +fn is_supported_collection(ident: &Ident) -> bool { +    // collections added here must implement IntoIterator & FromIterator +    // FromIterator must not require bounds like Eq or Ord since these are Self-referential +    ident == "Vec" || ident == "VecDeque" || ident == "LinkedList" +} +  impl AssocTypeConversions<'_> {      pub fn parse_type_path(&self, type_: &mut Type) -> Result<TypeTransform, TransformError> {          if !iter_type(type_).any(match_assoc_type) { @@ -120,6 +126,21 @@ impl AssocTypeConversions<'_> {                          }                      }                  } +            } else if is_supported_collection(ident) && path.segments.len() == 1 { +                let first_seg = path.segments.first_mut().unwrap(); + +                if let PathArguments::AngleBracketed(args) = &mut first_seg.arguments { +                    if args.args.len() == 1 { +                        if let GenericArgument::Type(generic_type) = args.args.first_mut().unwrap() +                        { +                            if iter_type(generic_type).any(match_assoc_type) { +                                return Ok(TypeTransform::Collection( +                                    self.parse_type_path(generic_type)?.into(), +                                )); +                            } +                        } +                    } +                }              } else {                  let last_seg = &path.segments.last().unwrap();                  if last_seg.ident == "Result" { | 
