use functor_derive::Functor;
use std::convert::{TryFrom, TryInto};
#[derive(Debug, PartialEq)]
enum T1 {
Mappable,
NotMappable(&'static str),
}
#[derive(Debug, PartialEq)]
struct T2;
#[derive(Debug, PartialEq)]
struct MappingError(&'static str);
#[test]
fn mapping_succeeds_when_function_succeeds() {
#[derive(Functor, Debug, PartialEq)]
struct Test<T>(T, T, T);
let src = Test(T1::Mappable, T1::Mappable, T1::Mappable);
let dst: Result<Test<T2>, _> = src.try_fmap(TryInto::try_into);
assert_eq!(dst, Ok(Test(T2, T2, T2)));
}
#[test]
fn mapping_fails_with_first_error_when_function_fails() {
#[derive(Functor, Debug, PartialEq)]
struct Test<T>(T, T, T);
let src = Test(
T1::NotMappable("First Error"),
T1::Mappable,
T1::NotMappable("Second Error"),
);
let dst: Result<Test<T2>, _> = src.try_fmap(TryInto::try_into);
assert_eq!(dst, Err(MappingError("First Error")));
}
impl TryFrom<T1> for T2 {
type Error = MappingError;
fn try_from(value: T1) -> Result<Self, Self::Error> {
match value {
T1::Mappable => Ok(T2),
T1::NotMappable(message) => Err(MappingError(message)),
}
}
}