Trait funcmap::TryFuncMap

source ·
pub trait TryFuncMap<A, B, P = TypeParam<0>>: Sizedwhere
    P: FuncMarker<P>,{
    type Output;

    // Required method
    fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>
       where F: FnMut(A) -> Result<B, E>;

    // Provided method
    fn try_func_map_over<Q, E, F>(self, f: F) -> Result<Self::Output, E>
       where F: FnMut(A) -> Result<B, E>,
             Q: FuncMarker<P> { ... }
}
Expand description

Fallible functorial mapping of a generic type over any of its type parameters

Deriving TryFuncMap

In most cases, implementations of this trait can and should be derived automatically:

#[derive(TryFuncMap)]
struct Foo<T> {
    // ...
}

See the crate-level documentation for details.

Manually Implementing TryFuncMap

If you need to implement TryFuncMap manually, make sure to uphold the following contract:

Let Foo be a type that is generic over the type or const parameters T0, ..., Tn.

If Foo implements TryFuncMap<A, B, TypeParam<N>>, then

  • N must be in the range 0..=n.
  • The parameter of Foo at index N (not counting lifetime parameters) must be A. In particular, it must be a type parameter, not a const generic.
  • Foo::Output must be Foo with the parameter at index N replaced with B.

Furthermore:

  • try_func_map_over must behave in exactly the same way as try_func_map. This is the default behavior and must not be changed.
  • If the closure provided to try_func_map fails, then the result must be the first error according to the order of the fields in the definition of Foo:
    #[derive(TryFuncMap, Copy, Clone, Debug, PartialEq)]
    struct Foo<T> {
        value1: T,
        value2: T,
    }
     
    let foo = Foo {
        value1: "1a",
        value2: ""
    };
    
    let result: Result<Foo<i32>, ParseIntError> = foo.try_func_map(|v| v.parse());
     
    assert!(result.is_err());
    assert_eq!(*result.unwrap_err().kind(), IntErrorKind::InvalidDigit);
  • When implementing TryFuncMap for different marker types TypeParam<N> and TypeParam<M>, the result of mapping over both type parameters in sequence must not depend on the order of the two mappings, i.e.
    foo.try_func_map_over::<TypeParam<N>, _, _>(f)
       .and_then(|x| x.try_func_map_over::<TypeParam<M>, _, _>(g))
    
    // must be equivalent to
    
    foo.try_func_map_over::<TypeParam<M>, _, _>(g)
       .and_then(|x| x.try_func_map_over::<TypeParam<N>, _, _>(f))

Required Associated Types§

source

type Output

The output type of the functorial mapping

This is Self with the parameter at index N replaced with B, where N is such that P is TypeParam<N>.

In the simplest case of a type with just a single type parameter, if Self is Foo<A>, then this is Foo<B>.

Required Methods§

source

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

Tries to apply the closure f to self in a functorial way

Errors

Fails if and only if f fails, returning the first error according to the order of the fields in the definition of Self

Provided Methods§

source

fn try_func_map_over<Q, E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>, Q: FuncMarker<P>,

Tries to apply the closure f to self in a functorial way, allowing explicit specification of the marker type P

This is a convenience method that has the exact same functionality as try_func_map but can be used to specify the marker type P in a convenient way in cases where it is ambiguous.

So if you have

#[derive(TryFuncMap, Debug, PartialEq)]
struct Foo<S, T> {
    s: S,
    t: T,
}

let foo = Foo {
    s: "42",
    t: "42",
};

then instead of writing

let bar = TryFuncMap::<_, _, TypeParam<1>>::try_func_map(foo, |v| v.parse::<i32>());
assert_eq!(bar, Ok(Foo { s: "42", t: 42 }));

you can more conveniently write

let bar = foo.try_func_map_over::<TypeParam<1>, _, _>(|v| v.parse::<i32>());
assert_eq!(bar, Ok(Foo { s: "42", t: 42 }));

This lets you chain method calls more easily as in

foo.try_func_map_over::<TypeParam<0>, _, _>(|v| v.parse::<i32>())
    .and_then(|foo| foo.try_func_map_over::<TypeParam<1>, _, _>(|v| v.parse::<i32>()))

Note that you still need to specify the inferred type _ for the error type E and the closure type F.

Errors

Fails if and only if f fails, returning the first error according to the order of the fields in the definition of Self

Implementations on Foreign Types§

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Box<A>

§

type Output = Box<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<K, A, B> TryFuncMap<A, B, TypeParam<1>> for IntoIter<K, A>where K: Ord,

§

type Output = IntoIter<K, B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, V> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A, V>where B: Eq + Hash,

§

type Output = IntoIter<B, V>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for BinaryHeap<A>where B: Ord,

§

type Output = BinaryHeap<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for RangeToInclusive<A>

§

type Output = RangeToInclusive<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>

§

type Output = IntoIter<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<T, A, B> TryFuncMap<A, B, TypeParam<1>> for Result<T, A>

§

type Output = Result<T, B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Option<A>

§

type Output = Option<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<B, T, U> TryFuncMap<T, U, TypeParam<1>> for ControlFlow<B, T>

§

type Output = ControlFlow<B, U>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(T) -> Result<U, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>

§

type Output = IntoIter<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for RangeTo<A>

§

type Output = RangeTo<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, U> TryFuncMap<A, B, TypeParam<0>> for Result<A, U>

§

type Output = Result<B, U>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<T, U, C> TryFuncMap<T, U, TypeParam<0>> for ControlFlow<T, C>

§

type Output = ControlFlow<U, C>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(T) -> Result<U, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for RangeFrom<A>

§

type Output = RangeFrom<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>where B: Ord,

§

type Output = IntoIter<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>

§

type Output = IntoIter<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>

§

type Output = IntoIter<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for RangeInclusive<A>

§

type Output = RangeInclusive<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Cell<A>

§

type Output = Cell<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<K, A, B, S> TryFuncMap<A, B, TypeParam<1>> for HashMap<K, A, S>where K: Eq + Hash,

§

type Output = HashMap<K, B, RandomState>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, const N: usize> TryFuncMap<A, B, TypeParam<0>> for [A; N]

§

type Output = [B; N]

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Range<A>

§

type Output = Range<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>where B: Ord,

§

type Output = IntoIter<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>

§

type Output = IntoIter<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for BTreeSet<A>where B: Ord,

§

type Output = BTreeSet<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Bound<A>

§

type Output = Bound<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for VecDeque<A>

§

type Output = VecDeque<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A>where B: Eq + Hash,

§

type Output = IntoIter<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<K, A, B> TryFuncMap<A, B, TypeParam<1>> for BTreeMap<K, A>where K: Ord,

§

type Output = BTreeMap<K, B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for RefCell<A>

§

type Output = RefCell<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, V> TryFuncMap<A, B, TypeParam<0>> for BTreeMap<A, V>where B: Ord,

§

type Output = BTreeMap<B, V, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, V> TryFuncMap<A, B, TypeParam<0>> for IntoIter<A, V>where B: Ord,

§

type Output = IntoIter<B, V, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for PhantomData<A>

§

type Output = PhantomData<B>

source§

fn try_func_map<E, F>(self, _: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for UnsafeCell<A>

§

type Output = UnsafeCell<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, S> TryFuncMap<A, B, TypeParam<0>> for HashSet<A, S>where B: Eq + Hash,

§

type Output = HashSet<B, RandomState>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Poll<A>

§

type Output = Poll<B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<K, A, B> TryFuncMap<A, B, TypeParam<1>> for IntoIter<K, A>where K: Eq + Hash,

§

type Output = IntoIter<K, B>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for LinkedList<A>

§

type Output = LinkedList<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B> TryFuncMap<A, B, TypeParam<0>> for Vec<A>

§

type Output = Vec<B, Global>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

source§

impl<A, B, V, S> TryFuncMap<A, B, TypeParam<0>> for HashMap<A, V, S>where B: Eq + Hash,

§

type Output = HashMap<B, V, RandomState>

source§

fn try_func_map<E, F>(self, f: F) -> Result<Self::Output, E>where F: FnMut(A) -> Result<B, E>,

Implementors§