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); let src = Test(T1::Mappable, T1::Mappable, T1::Mappable); let dst: Result, _> = 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); let src = Test( T1::NotMappable("First Error"), T1::Mappable, T1::NotMappable("Second Error"), ); let dst: Result, _> = src.try_fmap(TryInto::try_into); assert_eq!(dst, Err(MappingError("First Error"))); } impl TryFrom for T2 { type Error = MappingError; fn try_from(value: T1) -> Result { match value { T1::Mappable => Ok(T2), T1::NotMappable(message) => Err(MappingError(message)), } } }