Skip to content

Commit a23675f

Browse files
authored
Merge pull request #69 from TobiasvdVen/return-tuple
2 parents 1709758 + 4e0d15e commit a23675f

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

faux_macros/src/methods/morphed.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,11 @@ impl<'a> Signature<'a> {
180180
if self.is_async {
181181
proxy_real.extend(quote! { .await })
182182
}
183-
if let Some(wrapped_self) = self.wrap_self(morphed_ty, real_self, &proxy_real)? {
184-
proxy_real = wrapped_self;
183+
184+
if let Some(output) = self.output {
185+
if let Some(wrapped_self) = Self::wrap_self(output, morphed_ty, real_self, &proxy_real)? {
186+
proxy_real = wrapped_self;
187+
}
185188
}
186189

187190
let ret = match &self.method_data {
@@ -255,26 +258,24 @@ impl<'a> Signature<'a> {
255258
}
256259

257260
fn wrap_self(
258-
&self,
261+
ty: &Type,
259262
morphed_ty: &syn::TypePath,
260263
real_self: SelfType,
261264
block: &TokenStream,
262265
) -> darling::Result<Option<TokenStream>> {
263-
// TODO: use let-else once we bump MSRV to 1.65.0
264-
let output = match self.output {
265-
Some(output) => output,
266-
None => return Ok(None),
267-
};
268-
if !contains_self(output, morphed_ty) {
266+
if !contains_self(ty, morphed_ty) {
269267
return Ok(None);
270268
}
271269

272270
let is_self = |ty: &syn::TypePath| {
273271
ty == morphed_ty || (ty.qself.is_none() && ty.path.is_ident("Self"))
274272
};
275273

276-
let output = match output {
274+
let output = match ty {
277275
syn::Type::Path(output) => output,
276+
syn::Type::Tuple(tuple) => {
277+
return Self::wrap_self_tuple(block, tuple, morphed_ty, real_self);
278+
},
278279
output => return Err(unhandled_self_return(output)),
279280
};
280281

@@ -341,6 +342,32 @@ impl<'a> Signature<'a> {
341342

342343
Ok(Some(wrapped))
343344
}
345+
346+
fn wrap_self_tuple(
347+
block: &TokenStream,
348+
tuple: &syn::TypeTuple,
349+
morphed_ty: &syn::TypePath,
350+
real_self: SelfType) -> darling::Result<Option<TokenStream>> {
351+
let elements = tuple.elems
352+
.iter()
353+
.enumerate()
354+
.map(|e| {
355+
let index = syn::Index::from(e.0);
356+
let ty = e.1;
357+
358+
let tuple_index = quote! { tuple.#index };
359+
let wrapped = Self::wrap_self(ty, morphed_ty, real_self, &tuple_index)?;
360+
361+
Ok(wrapped.unwrap_or(tuple_index))
362+
})
363+
.collect::<darling::Result<Vec<TokenStream>>>()?;
364+
365+
Ok(Some(quote! {{
366+
let tuple = #block;
367+
368+
(# ( #elements),*)
369+
}}))
370+
}
344371
}
345372

346373
impl MethodData<'_> {

tests/return_self_tuple.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use std::sync::Arc;
2+
use std::rc::Rc;
3+
use std::result::Result;
4+
use std::error::Error;
5+
6+
#[faux::create]
7+
pub struct Foo;
8+
9+
#[faux::methods]
10+
impl Foo {
11+
pub fn self_self() -> (Self, Self) {
12+
(Foo, Foo)
13+
}
14+
15+
pub fn self_path() -> (Self, i32) {
16+
(Foo, 1)
17+
}
18+
19+
pub fn self_box() -> (Self, Box<Self>) {
20+
(Foo, Box::new(Foo))
21+
}
22+
23+
pub fn self_rc() -> (Self, Rc<Self>) {
24+
(Foo, Rc::new(Foo))
25+
}
26+
27+
pub fn self_arc() -> (Self, Arc<Self>) {
28+
(Foo, Arc::new(Foo))
29+
}
30+
31+
pub fn self_result() -> (Self, Result<Self, Box<dyn Error>>) {
32+
(Foo, Ok(Foo))
33+
}
34+
35+
pub fn self_option() -> (Self, Option<Self>) {
36+
(Foo, Some(Foo))
37+
}
38+
}

0 commit comments

Comments
 (0)