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