use super::*;
use ::std::convert::Infallible;
use ::std::num::TryFromIntError;
#[derive(Debug, Clone, PartialEq, Default)]
struct Small(u8);
#[derive(Debug, Clone, PartialEq, Default)]
struct Large(u32);
impl TryFrom<&Large> for Small {
type Error = TryFromIntError;
fn try_from(value: &Large) -> Result<Self, Self::Error> {
value.0.try_into().map(Small)
}
}
impl TryFrom<&Small> for Large {
type Error = Infallible;
fn try_from(value: &Small) -> Result<Self, Self::Error> {
Ok(Large(value.0 as u32))
}
}
#[test]
fn test_std_converter() {
let converter = StdConverter;
assert_eq!(converter.convert_to_right(&Small(42)), Ok(Large(42)));
assert_eq!(converter.convert_to_left(&Large(200)), Ok(Small(200)));
assert!(converter.convert_to_left(&Large(300)).is_err());
}
#[test]
fn test_fn_converter() {
let converter = fn_converter(
|u: &u8| -> Result<i32, Infallible> { Ok((*u as i32).wrapping_add(10)) },
|i: &i32| -> Result<u8, TryFromIntError> { i.wrapping_sub(10).try_into() },
);
assert_eq!(converter.convert_to_right(&42), Ok(32));
assert_eq!(converter.convert_to_left(&32), Ok(42));
assert!(converter.convert_to_right(&300).is_err());
}
#[test]
fn test_boxed_fn_converter() {
let converter = boxed_fn_converter(
|u: &u8| -> Result<i32, Infallible> { Ok((*u as i32).wrapping_add(100)) },
|i: &i32| -> Result<u8, TryFromIntError> { i.wrapping_sub(100).try_into() },
);
assert_eq!(converter.convert_to_right(&150), Ok(50));
assert_eq!(converter.convert_to_left(&50), Ok(150));
assert!(converter.convert_to_right(&50).is_err());
}
#[test]
fn test_pair_basic() {
let pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.left_opt(), Some(&Small(42)));
assert_eq!(pair.right_opt(), None);
let pair = Pair::<Small, Large>::from_right(Large(100));
assert_eq!(pair.left_opt(), None);
assert_eq!(pair.right_opt(), Some(&Large(100)));
}
#[test]
fn test_pair_try_conversion() {
let pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.try_right(), Ok(&Large(42))); assert_eq!(pair.try_left(), Ok(&Small(42))); assert_eq!(pair.right_opt(), Some(&Large(42)));
let pair = Pair::<Small, Large>::from_right(Large(200));
assert_eq!(pair.try_left(), Ok(&Small(200))); assert_eq!(pair.try_right(), Ok(&Large(200))); assert_eq!(pair.left_opt(), Some(&Small(200)));
let pair = Pair::<Small, Large>::from_right(Large(300));
assert!(pair.try_left().is_err()); assert_eq!(pair.try_right(), Ok(&Large(300))); assert_eq!(pair.left_opt(), None);
let pair = Pair::<Small, Large>::from_left(Small(42));
let _ = pair.right(); assert_eq!(pair.try_right(), Ok(&Large(42))); assert_eq!(pair.try_left(), Ok(&Small(42))); assert_eq!(pair.try_right(), Ok(&Large(42))); }
#[test]
fn test_pair_try_into() {
let pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.try_into_right(), Ok(Large(42)));
let pair = Pair::<Small, Large>::from_right(Large(200));
assert_eq!(pair.try_into_left(), Ok(Small(200)));
let pair = Pair::<Small, Large>::from_right(Large(300));
assert!(pair.try_into_left().is_err());
let pair = Pair::<Small, Large>::from_left(Small(42));
let _ = pair.try_right(); assert_eq!(pair.try_into_right(), Ok(Large(42)));
let pair = Pair::<Small, Large>::from_right(Large(200));
let _ = pair.try_left(); assert_eq!(pair.try_into_left(), Ok(Small(200)));
}
#[test]
fn test_pair_try_mut() {
let mut pair = Pair::<Small, Large>::from_left(Small(42));
let left = pair.try_left_mut().unwrap();
*left = Small(43);
assert_eq!(pair.left_opt(), Some(&Small(43)));
assert_eq!(pair.right_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
let right = pair.try_right_mut().unwrap();
*right = Large(201);
assert_eq!(pair.right_opt(), Some(&Large(201)));
assert_eq!(pair.left_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
let left = pair.try_left_mut().unwrap();
*left = Small(42);
assert_eq!(pair.left_opt(), Some(&Small(42)));
assert_eq!(pair.right_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(300));
assert!(pair.try_left_mut().is_err());
assert_eq!(pair.right_opt(), Some(&Large(300)));
let mut pair = Pair::<Small, Large>::from_left(Small(42));
let _ = pair.try_right(); assert_eq!(pair.right_opt(), Some(&Large(42)));
let right = pair.try_right_mut().unwrap();
*right = Large(43);
assert_eq!(pair.right_opt(), Some(&Large(43)));
assert_eq!(pair.left_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
let _ = pair.try_left(); assert_eq!(pair.left_opt(), Some(&Small(200)));
let left = pair.try_left_mut().unwrap();
*left = Small(201);
assert_eq!(pair.left_opt(), Some(&Small(201)));
assert_eq!(pair.right_opt(), None); }
#[test]
fn test_pair_opt_mut() {
let mut pair = Pair::<Small, Large>::from_left(Small(42));
let left = pair.left_opt_mut().unwrap();
*left = Small(43);
assert_eq!(pair.left_opt(), Some(&Small(43)));
assert_eq!(pair.right_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
let right = pair.right_opt_mut().unwrap();
*right = Large(201);
assert_eq!(pair.right_opt(), Some(&Large(201)));
assert_eq!(pair.left_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
assert_eq!(pair.left_opt_mut(), None);
assert_eq!(pair.right_opt(), Some(&Large(200)));
let mut pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.right_opt_mut(), None);
assert_eq!(pair.left_opt(), Some(&Small(42)));
let mut pair = Pair::<Small, Large>::from_left(Small(42));
let _ = pair.try_right(); assert_eq!(pair.right_opt(), Some(&Large(42)));
let left = pair.left_opt_mut().unwrap();
*left = Small(43);
assert_eq!(pair.left_opt(), Some(&Small(43)));
assert_eq!(pair.right_opt(), None);
let mut pair = Pair::<Small, Large>::from_right(Large(200));
let _ = pair.try_left(); assert_eq!(pair.left_opt(), Some(&Small(200)));
let right = pair.right_opt_mut().unwrap();
*right = Large(201);
assert_eq!(pair.right_opt(), Some(&Large(201)));
assert_eq!(pair.left_opt(), None); }
#[test]
fn test_try_extract_left() {
let mut pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.try_extract_left(), Ok(Some(Small(42))));
assert_eq!(pair.left_opt(), None);
assert_eq!(pair.right_opt(), Some(&Large(42)));
let mut pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.try_right(), Ok(&Large(42))); assert_eq!(pair.try_extract_left(), Ok(Some(Small(42))));
assert_eq!(pair.left_opt(), None);
assert_eq!(pair.right_opt(), Some(&Large(42)));
let mut pair = Pair::<Small, Large>::from_right(Large(100));
assert_eq!(pair.try_extract_left(), Ok(None));
assert_eq!(pair.left_opt(), None);
assert_eq!(pair.right_opt(), Some(&Large(100)));
}
#[test]
fn test_try_extract_right() {
let mut pair = Pair::<Small, Large>::from_right(Large(200));
assert_eq!(pair.try_extract_right(), Ok(Some(Large(200))));
assert_eq!(pair.right_opt(), None);
assert_eq!(pair.left_opt(), Some(&Small(200)));
let mut pair = Pair::<Small, Large>::from_right(Large(200));
assert_eq!(pair.try_left(), Ok(&Small(200))); assert_eq!(pair.try_extract_right(), Ok(Some(Large(200))));
assert_eq!(pair.right_opt(), None);
assert_eq!(pair.left_opt(), Some(&Small(200)));
let mut pair = Pair::<Small, Large>::from_left(Small(42));
assert_eq!(pair.try_extract_right(), Ok(None));
assert_eq!(pair.right_opt(), None);
assert_eq!(pair.left_opt(), Some(&Small(42)));
let mut pair = Pair::<Small, Large>::from_right(Large(300));
assert!(pair.try_extract_right().is_err());
}
#[test]
fn test_pair_method_existence() {
#[derive(Debug, Clone, PartialEq, Default)]
struct A(u32);
#[derive(Debug, Clone, PartialEq, Default)]
struct B(u32);
impl TryFrom<&A> for B {
type Error = Infallible;
fn try_from(value: &A) -> Result<Self, Self::Error> {
Ok(B(value.0))
}
}
impl TryFrom<&B> for A {
type Error = Infallible;
fn try_from(value: &B) -> Result<Self, Self::Error> {
Ok(A(value.0))
}
}
let pair = Pair::<A, B>::from_left(A(42));
let mut pair_mut = Pair::<A, B>::from_left(A(42));
let _: Pair<A, B> = Pair::from_left(A(42));
let _: Pair<A, B> = Pair::from_right(B(100));
let _: Pair<A, B> = Pair::from_left_conv(A(42), StdConverter::default());
let _: Pair<A, B> = Pair::from_right_conv(B(100), StdConverter::default());
let _: Option<&A> = pair.left_opt();
let _: Option<&B> = pair.right_opt();
let _: Result<&A, Infallible> = pair.try_left();
let _: Result<&B, Infallible> = pair.try_right();
let _: &A = Pair::<A, B>::from_left(A(42)).left();
let _: &B = Pair::<A, B>::from_right(B(100)).right();
let _: &A = unsafe { pair.left_with(|r| A(r.0)) };
let _: &B = unsafe { pair.right_with(|l| B(l.0)) };
let _: Result<&A, &str> = unsafe { pair.try_left_with(|r| Ok(A(r.0))) };
let _: Result<&B, &str> = unsafe { pair.try_right_with(|l| Ok(B(l.0))) };
let _: Option<&mut A> = pair_mut.left_opt_mut();
let _: Option<&mut B> = pair_mut.right_opt_mut();
let _: Result<&mut A, Infallible> = pair_mut.try_left_mut();
let _: Result<&mut B, Infallible> = pair_mut.try_right_mut();
let _: Result<&mut A, &str> = unsafe { pair_mut.try_left_mut_with(|r| Ok(A(r.0))) };
let _: Result<&mut B, &str> = unsafe { pair_mut.try_right_mut_with(|l| Ok(B(l.0))) };
let _: &mut A = unsafe { pair_mut.left_mut_with(|r| A(r.0)) };
let _: &mut B = unsafe { pair_mut.right_mut_with(|l| B(l.0)) };
let pair = Pair::<A, B>::from_left(A(42));
let _: Result<A, Infallible> = pair.try_into_left();
let pair = Pair::<A, B>::from_left(A(42));
let _: Result<B, Infallible> = pair.try_into_right();
let converter = fn_converter(
|_: &B| -> Result<A, Infallible> { Ok(A(42)) },
|_: &A| -> Result<B, Infallible> { Ok(B(42)) },
);
let pair = Pair::from_left_conv(A(42), converter.clone());
let _: A = pair.into_left();
let pair = Pair::from_left_conv(A(42), converter);
let _: B = pair.into_right();
let pair = Pair::<A, B>::from_left(A(42));
let _: Result<A, &str> = unsafe { pair.clone().try_into_left_with(|r| Ok(A(r.0))) };
let _: Result<B, &str> = unsafe { pair.clone().try_into_right_with(|l| Ok(B(l.0))) };
let _: A = unsafe { pair.clone().into_left_with(|r| A(r.0)) };
let _: B = unsafe { pair.clone().into_right_with(|l| B(l.0)) };
let _: Option<A> = pair_mut.extract_left();
let _: Option<B> = pair_mut.extract_right();
let _: Result<Option<A>, Infallible> = pair_mut.try_extract_left();
let _: Result<Option<B>, Infallible> = pair_mut.try_extract_right();
let _: Option<A> = unsafe { pair_mut.extract_left_with(|r| B(r.0)) };
let _: Option<B> = unsafe { pair_mut.extract_right_with(|l| A(l.0)) };
let _: Result<Option<A>, &str> = unsafe { pair_mut.try_extract_left_with(|r| Ok(B(r.0))) };
let _: Result<Option<B>, &str> = unsafe { pair_mut.try_extract_right_with(|l| Ok(A(l.0))) };
let _: EitherOrBoth<&A, &B> = pair.as_ref();
}