Implement tuple mapping (#2247)
* implement tuple mapping * docs, clippy magic * clippy >:( * rename for clarity
This commit is contained in:
parent
65af5a7f78
commit
058e15f547
@ -740,6 +740,43 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for structs which are capable of mapping a given type to another.
|
||||
pub trait MappingFunctor<T> {
|
||||
/// The result of the mapping operation.
|
||||
type Output;
|
||||
|
||||
/// The actual mapping operation.
|
||||
fn apply(&mut self, from: T) -> Self::Output;
|
||||
}
|
||||
|
||||
/// Map all entries in a tuple to another type, dependent on the tail type.
|
||||
pub trait Map<M> {
|
||||
/// The result of the mapping operation.
|
||||
type MapResult;
|
||||
|
||||
/// Perform the mapping!
|
||||
fn map(self, mapper: M) -> Self::MapResult;
|
||||
}
|
||||
|
||||
impl<Head, Tail, M> Map<M> for (Head, Tail)
|
||||
where
|
||||
M: MappingFunctor<Head>,
|
||||
Tail: Map<M>,
|
||||
{
|
||||
type MapResult = (M::Output, Tail::MapResult);
|
||||
|
||||
fn map(self, mut mapper: M) -> Self::MapResult {
|
||||
let head = mapper.apply(self.0);
|
||||
(head, self.1.map(mapper))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Map<M> for () {
|
||||
type MapResult = ();
|
||||
|
||||
fn map(self, _mapper: M) -> Self::MapResult {}
|
||||
}
|
||||
|
||||
/// Iterate over a tuple, executing the given `expr` for each element.
|
||||
#[macro_export]
|
||||
#[allow(clippy::items_after_statements)]
|
||||
@ -856,9 +893,11 @@ impl<Head, Tail> PlusOne for (Head, Tail) where
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use tuple_list::{tuple_list, tuple_list_type};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::ownedref::OwnedMutSlice;
|
||||
use crate::tuples::type_eq;
|
||||
use crate::tuples::{type_eq, Map, MappingFunctor};
|
||||
|
||||
#[test]
|
||||
#[allow(unused_qualifications)] // for type name tests
|
||||
@ -902,4 +941,29 @@ mod test {
|
||||
crate::ownedref::OwnedMutSlice<u32>,
|
||||
>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mapper() {
|
||||
struct W<T>(T);
|
||||
struct MyMapper;
|
||||
|
||||
impl<T> MappingFunctor<T> for MyMapper {
|
||||
type Output = W<T>;
|
||||
|
||||
fn apply(&mut self, from: T) -> Self::Output {
|
||||
W(from)
|
||||
}
|
||||
}
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
struct C;
|
||||
|
||||
let orig = tuple_list!(A, B, C);
|
||||
let mapped = orig.map(MyMapper);
|
||||
|
||||
// this won't compile if the mapped type is not correct
|
||||
#[allow(clippy::no_effect_underscore_binding)]
|
||||
let _type_assert: tuple_list_type!(W<A>, W<B>, W<C>) = mapped;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user