pub trait Mapper<T> {
type Output;
type NextMapper;
// Required method
fn map(self, value: T) -> (Self::Output, Self::NextMapper);
}
Expand description
Define mappers for traversing the tuple.
To traverse a tuple with type Tuple<T0, T1, ... Tn>
, you need to construct a custom mapper type,
which implements Mapper<T0>
, Mapper<T1>
… Mapper<Tn>
.
Pass your mapper to tuple’s foreach()
method, then the tuple will call
mapper’s map()
method in order of its elements and move the elements in.
NOTE: Traversing a tuple will consume it. If this is not what you want, call as_ref()
or as_mut()
to create a new tuple that references its all members before traversing.
Tip: Mapper
map elements by their types. If you are looking for a way to map elements by their order,
then what you are looking for is to
pass a tuple containing callable objects into fold()
method.
§Quickly build a mapper by macros
Here are two ways you can quickly build a folder.
§Traverse tuples by element types
The mapper!
macro helps you build a mapper that traverses tuples according to their element types.
For example:
use tuplez::{mapper, tuple, TupleLike};
let tup = tuple!(1, "hello", 3.14).foreach(mapper! {
|x: i32| -> i64 { x as i64 }
|x: f32| -> String { x.to_string() }
<'a> |x: &'a str| -> &'a [u8] { x.as_bytes() }
});
assert_eq!(tup, tuple!(1i64, b"hello" as &[u8], "3.14".to_string()));
§Traverse tuples in order of their elements
You can create a new tuple with the same number of elements, whose elements are all callable objects that accepts an element
and returns another value (FnOnce(T) -> U
), then, you can use that tuple as a mapper.
use tuplez::{tuple, TupleLike};
let tup = tuple!(1, 2, 3);
let result = tup.foreach(
tuple!(
|x| x as f32,
|x: i32| x.to_string(),
|x: i32| Some(x),
)
);
assert_eq!(result, tuple!(1.0, "2".to_string(), Some(3)));
§Custom mapper
For more complex cases that cannot be covered by the mapper!
macro,
for example, you want to save some results into context variables,
you need to implement Mapper<Ti>
for your mapper for all element type Ti
s in tuples.
Generic can be used.
For example:
use tuplez::{foreach::Mapper, tuple, TupleLike};
struct MyElement(i32);
struct Collector<'a>(&'a mut Vec<String>);
impl<T: ToString> Mapper<&T> for Collector<'_> {
type Output = ();
type NextMapper = Self;
fn map(self, value: &T) -> (Self::Output, Self::NextMapper) {
(
self.0.push(format!(
"{} : {}",
std::any::type_name::<T>(),
value.to_string()
)),
self,
)
}
}
impl Mapper<&MyElement> for Collector<'_> {
type Output = ();
type NextMapper = Self;
fn map(self, value: &MyElement) -> (Self::Output, Self::NextMapper) {
(self.0.push(format!("MyElement : {}", value.0)), self)
}
}
let mut buffers = vec![];
let collector = Collector(&mut buffers);
tuple!(1, "hello", MyElement(14))
.as_ref()
.foreach(collector);
assert_eq!(
buffers,
vec![
"i32 : 1".to_string(),
"&str : hello".to_string(),
"MyElement : 14".to_string()
]
);
Required Associated Types§
sourcetype NextMapper
type NextMapper
Type of next mapper to be use.
Required Methods§
sourcefn map(self, value: T) -> (Self::Output, Self::NextMapper)
fn map(self, value: T) -> (Self::Output, Self::NextMapper)
Map an element to another value.