1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
//! Traits that provide generic functionality for multiple types in frunk
/// An alternative to AsRef that does not force the reference type to be a pointer itself.
///
/// This lets us create implementations for our recursive traits that take the resulting
/// Output reference type, without having to deal with strange, spurious overflows
/// that sometimes occur when trying to implement a trait for &'a T (see this comment:
/// <https://github.com/lloydmeta/frunk/pull/106#issuecomment-377927198>)
///
/// This functionality is also provided as an inherent method [on HLists] and [on Coproducts].
/// However, you may find this trait useful in generic contexts.
///
/// [on HLists]: ../hlist/struct.HCons.html#method.to_ref
/// [on Coproducts]: ../coproduct/enum.Coproduct.html#method.to_ref
pub trait ToRef<'a> {
type Output;
fn to_ref(&'a self) -> Self::Output;
}
/// An alternative to `AsMut` that does not force the reference type to be a pointer itself.
///
/// This parallels [`ToRef`]; see it for more information.
///
/// [`ToRef`]: trait.ToRef.html
pub trait ToMut<'a> {
type Output;
fn to_mut(&'a mut self) -> Self::Output;
}
/// Trait that allows for reversing a given data structure.
///
/// Implemented for HLists.
///
/// This functionality is also provided as an [inherent method].
/// However, you may find this trait useful in generic contexts.
///
/// [inherent method]: ../hlist/struct.HCons.html#method.into_reverse
pub trait IntoReverse {
type Output;
/// Reverses a given data structure.
fn into_reverse(self) -> Self::Output;
}
/// Wrapper type around a function for polymorphic maps and folds.
///
/// This is a thin generic wrapper type that is used to differentiate
/// between single-typed generic closures `F` that implements, say, `Fn(i8) -> bool`,
/// and a Poly-typed `F` that implements multiple Function types
/// via the [`Func`] trait. (say, `Func<i8, Output=bool>` and `Func<bool, Output=f32>`)
///
/// This is needed because there are completely generic impls for many of the
/// HList traits that take a simple unwrapped closure.
///
/// [`Func`]: trait.Func.html
#[derive(Debug, Copy, Clone, Default)]
pub struct Poly<T>(pub T);
/// This is a simple, user-implementable alternative to `Fn`.
///
/// Might not be necessary if/when Fn(Once, Mut) traits are implementable
/// in stable Rust
pub trait Func<Input> {
type Output;
/// Call the `Func`.
///
/// Notice that this does not take a self argument, which in turn means `Func`
/// cannot effectively close over a context. This decision trades power for convenience;
/// a three-trait `Fn` heirarchy like that in std provides a great deal of power in a
/// small fraction of use-cases, but it also comes at great expanse to the other 95% of
/// use cases.
fn call(i: Input) -> Self::Output;
}