#![feature(try_trait_v2)]
use std::ops::{ControlFlow, FromResidual, Try};
#[allow(dead_code)]
trait Transpose<U, O>
where
Self: Try,
Self::Output: Try<Output = O, Residual = U::Residual>,
U: Try,
U::Output: Try<Output = O, Residual = Self::Residual>,
{
fn transpose2(self) -> U;
}
impl<T, U, O> Transpose<U, O> for T
where
T: Try,
T::Output: Try<Output = O, Residual = U::Residual>,
U: Try,
U::Output: Try<Output = O, Residual = T::Residual>,
{
fn transpose2(self) -> U {
match self.branch() {
ControlFlow::Continue(inner_u) => match inner_u.branch() {
ControlFlow::Continue(val) => {
let inner_t = Try::from_output(val);
U::from_output(inner_t)
}
ControlFlow::Break(u_residual) => U::from_residual(u_residual),
},
ControlFlow::Break(t_residual) => {
let inner_t = FromResidual::from_residual(t_residual);
U::from_output(inner_t)
}
}
}
}
#[test]
fn ok_some() {
let ok_some: Result<Option<u32>, String> = Ok(Some(5));
let stdlib: Option<Result<u32, String>> = ok_some.clone().transpose();
let custom: Option<Result<u32, String>> = ok_some.transpose2();
assert_eq!(stdlib, custom)
}
#[test]
fn ok_none() {
let ok_none: Result<Option<u32>, String> = Ok(None);
let stdlib = ok_none.clone().transpose();
let custom = ok_none.transpose2();
assert_eq!(stdlib, custom)
}
#[test]
fn err() {
let err: Result<Option<i32>, String> = Err("Oops".to_string());
let stdlib = err.clone().transpose();
let custom = err.transpose2();
assert_eq!(stdlib, custom)
}
#[test]
fn some_ok() {
let some_ok: Option<Result<u32, String>> = Some(Ok(5));
let stdlib: Result<Option<u32>, String> = some_ok.clone().transpose();
let custom: Result<Option<u32>, String> = some_ok.transpose2();
assert_eq!(stdlib, custom)
}
#[test]
fn some_err() {
let some_err: Option<Result<u32, String>> = Some(Err("Oops".to_string()));
let stdlib = some_err.clone().transpose();
let custom = some_err.transpose2();
assert_eq!(stdlib, custom)
}
#[test]
fn none() {
let none: Option<Result<u32, String>> = None;
let stdlib = none.clone().transpose();
let custom = none.transpose2();
assert_eq!(stdlib, custom)
}
fn main() {}