From 19dcb405cd4cfb960f51edbc1446e0a843772d6b Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Tue, 23 Nov 2021 06:00:26 +0100 Subject: support tuples --- README.md | 1 + src/lib.rs | 9 +++++++++ src/parse_trait_sig.rs | 1 + src/transform.rs | 8 +++++++- tests/tests.rs | 4 ++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 555e7f1..ab688ee 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Dynamize can convert associated types in: Dynamize also understands if you wrap associated types in the following types: +* tuples * `Option<_>` * `Result<_, _>` * `some::module::Result<_>` (type alias with fixed error type) diff --git a/src/lib.rs b/src/lib.rs index dbac013..3656bf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -473,6 +473,15 @@ impl TypeTransform { quote! {#arg.map_err(|x| #err_inner)} } } + TypeTransform::Tuple(types) => { + let idents = (0..types.len()).map(|i| format_ident!("v{}", i)); + // FUTURE: let transforms = std::iter::zip(idents, types).map(|(i, t)| t.convert(quote! {#i})); + let transforms = types.iter().enumerate().map(|(idx, t)| { + let id = format_ident!("v{}", idx); + t.convert(quote! {#id}) + }); + quote! { {let (#(#idents),*) = #arg; (#(#transforms),*)} } + } TypeTransform::IntoIterMapCollect(types) => { let idents = (0..types.len()).map(|i| format_ident!("v{}", i)); // FUTURE: let transforms = std::iter::zip(idents, types).map(|(i, t)| t.convert(quote! {#i})); diff --git a/src/parse_trait_sig.rs b/src/parse_trait_sig.rs index dfe3ce7..1267707 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), + Tuple(Vec), IntoIterMapCollect(Vec), Iterator(BoxType, Box), Result(Box, Box), diff --git a/src/transform.rs b/src/transform.rs index 11a98c2..ddab158 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -61,7 +61,13 @@ impl TypeConverter<'_> { return Ok(TypeTransform::NoOp); } - if let Type::Reference(TypeReference { + if let Type::Tuple(tuple) = type_ { + let mut types = Vec::new(); + for elem in &mut tuple.elems { + types.push(self.convert_type(elem)?); + } + return Ok(TypeTransform::Tuple(types)); + } else if let Type::Reference(TypeReference { lifetime: None, mutability: Some(_), elem, diff --git a/tests/tests.rs b/tests/tests.rs index 1bff07f..e30b0ef 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -31,6 +31,10 @@ fn it_works() { // also support Result type aliases with a fixed error type fn test8(&self) -> some::module::Result; + fn test9(&self) -> (Self::A, Self::B); + #[allow(clippy::type_complexity)] + fn test10(&self) -> (Self::A, (Self::A, Self::B), Self::B); + // fn test9(&self) -> &dyn Iterator; fn mut1(&mut self) -> Self::A; -- cgit v1.2.3