Trait TryFuncMap

Source
pub trait TryFuncMap<A, B, P = TypeParam<0>>: Sized
where 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

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

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

Source§

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> for Option<A>

Source§

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<A, B> TryFuncMap<A, B> for Poll<A>

Source§

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<A, B> TryFuncMap<A, B> for Box<A>

Source§

type Output = Box<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> for BinaryHeap<A>
where B: Ord,

Source§

type Output = BinaryHeap<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> for IntoIter<A>
where B: Ord,

Source§

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> for BTreeSet<A>
where B: Ord,

Source§

type Output = BTreeSet<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> for IntoIter<A>
where B: Ord,

Source§

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> for IntoIter<A>

Source§

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> for LinkedList<A>

Source§

type Output = LinkedList<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> for IntoIter<A>

Source§

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> for VecDeque<A>

Source§

type Output = VecDeque<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> for IntoIter<A>

Source§

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> for Vec<A>

Source§

type Output = Vec<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> for Cell<A>

Source§

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<A, B> TryFuncMap<A, B> for RefCell<A>

Source§

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> TryFuncMap<A, B> for UnsafeCell<A>

Source§

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> TryFuncMap<A, B> for PhantomData<A>

Source§

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> for Range<A>

Source§

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> for RangeFrom<A>

Source§

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> for RangeInclusive<A>

Source§

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> for RangeTo<A>

Source§

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> TryFuncMap<A, B> for RangeToInclusive<A>

Source§

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> for IntoIter<A>

Source§

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> for IntoIter<A>

Source§

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> for IntoIter<A>
where B: Eq + Hash,

Source§

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, S> TryFuncMap<A, B> for HashSet<A, S>
where B: Eq + Hash,

Source§

type Output = HashSet<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> for Result<A, U>

Source§

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<A, B, V> TryFuncMap<A, B> for BTreeMap<A, V>
where B: Ord,

Source§

type Output = BTreeMap<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, V> TryFuncMap<A, B> for IntoIter<A, V>
where B: Ord,

Source§

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, V> TryFuncMap<A, B> for IntoIter<A, V>
where B: Eq + Hash,

Source§

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, V, S> TryFuncMap<A, B> for HashMap<A, V, S>
where B: Eq + Hash,

Source§

type Output = HashMap<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, const N: usize> TryFuncMap<A, B> for [A; N]

Source§

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<B, T, U> TryFuncMap<T, U, TypeParam<1>> for ControlFlow<B, T>

Source§

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<K, A, B> TryFuncMap<A, B, TypeParam<1>> for BTreeMap<K, A>
where K: Ord,

Source§

type Output = BTreeMap<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<K, A, B> TryFuncMap<A, B, TypeParam<1>> for IntoIter<K, A>
where K: Ord,

Source§

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<K, A, B> TryFuncMap<A, B, TypeParam<1>> for IntoIter<K, A>
where K: Eq + Hash,

Source§

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<K, A, B, S> TryFuncMap<A, B, TypeParam<1>> for HashMap<K, A, S>
where K: Eq + Hash,

Source§

type Output = HashMap<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<T, A, B> TryFuncMap<A, B, TypeParam<1>> for Result<T, A>

Source§

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<T, U, C> TryFuncMap<T, U> for ControlFlow<T, C>

Source§

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>,

Implementors§