struct Done(T); impl Done { fn w1(self) -> Self { self } fn w2(self) -> Self { self } fn w3(self) -> Self { self } fn done(self) -> T { self.0 } } struct A; struct B; struct C; struct D; trait M0 { type R; fn e0(self) -> Self::R; } impl M0 for A { type R = String; fn e0(self) -> Self::R { "A".to_string() } } struct W0(T); impl W0 { fn w0(self) -> Done<::R> { println!("arm 0 succeeded"); Done(M0::e0(self.0)) } } trait C0 { type R; fn w0(self) -> Self::R; } impl C0 for W0 { type R = W1; fn w0(self) -> Self::R { println!("arm 0 failed"); W1(self.0) } } //========================= trait M1 { type R; fn e1(self) -> Self::R; } impl M1 for B { type R = String; fn e1(self) -> Self::R { "B".to_string() } } struct W1(T); impl W1 { fn w1(self) -> Done<::R> { println!("arm 1 succeeded"); Done(M1::e1(self.0)) } } trait C1 { type R; fn w1(self) -> Self::R; } impl C1 for W1 { type R = W2; fn w1(self) -> Self::R { println!("arm 1 failed"); W2(self.0) } } //========================= trait M2 { type R; fn e2(self) -> Self::R; } impl M2 for C { type R = String; fn e2(self) -> Self::R { "C".to_string() } } struct W2(T); impl W2 { fn w2(self) -> Done<::R> { println!("arm 2 succeeded"); Done(M2::e2(self.0)) } } trait C2 { type R; fn w2(self) -> Self::R; } impl C2 for W2 { type R = W3; fn w2(self) -> Self::R { println!("arm 2 failed"); W3(self.0) } } struct W3(T); impl W3 { fn done(self) -> () { () } } fn main() { println!("{:?}", W0(A).w0().w1().w2().done()); println!("{:?}", W0(B).w0().w1().w2().done()); println!("{:?}", W0(C).w0().w1().w2().done()); println!("{:?}", W0(D).w0().w1().w2().done()); }