aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-23 06:00:26 +0100
committerMartin Fischer <martin@push-f.com>2021-11-23 06:43:22 +0100
commit19dcb405cd4cfb960f51edbc1446e0a843772d6b (patch)
treefbd4a80460a20faea6975ae51939f463b612a6e3
parentb4acbbf52be85595cf8dcb839217fc4e2958328e (diff)
support tuples
-rw-r--r--README.md1
-rw-r--r--src/lib.rs9
-rw-r--r--src/parse_trait_sig.rs1
-rw-r--r--src/transform.rs8
-rw-r--r--tests/tests.rs4
5 files changed, 22 insertions, 1 deletions
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<TypeTransform>),
+ Tuple(Vec<TypeTransform>),
IntoIterMapCollect(Vec<TypeTransform>),
Iterator(BoxType, Box<TypeTransform>),
Result(Box<TypeTransform>, Box<TypeTransform>),
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<Self::A>;
+ 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<Item = Self::A>;
fn mut1(&mut self) -> Self::A;