pub trait Mapper<T> {
type Output;
// Required method
fn map(&mut self, value: &T) -> Self::Output;
}Expand description
Define functors for traversing the tuple by immutable references to tuple’s elements.
To traverse a tuple with type Tuple<T0, T1, ... Tn>, you need to construct a custom functor type,
which implements Mapper<T0>, Mapper<T1> … Mapper<Tn>.
Pass your functor to tuple’s foreach() method, then the tuple will call
functor’s map() method in order of its elements and pass in the immutable reference
of the element.
§The mapper! macro
There is a mapper! macro that helps you build a functor simply, here is an example:
use tuplez::*;
let tup = tuple!(1, "hello", 3.14).foreach(mapper!{
x: i32 => i64: *x as i64;
x: f32 => String: x.to_string();
x, 'a: &'a str => &'a [u8]: x.as_bytes()
});
assert_eq!(tup, tuple!(1i64, b"hello" as &[u8], "3.14".to_string()));Check the documentation page of mapper! for detailed syntax.
§Custom functor
For more complex cases that cannot be covered by the mapper! macro, for example, you want to save some results
inside your functor, you need to implement Mapper<Ti> for your functor for all element type Tis in tuples.
Generic can be used.
For example:
use tuplez::*;
struct MyElement(i32);
#[derive(Default)]
struct Collector(Vec<String>);
impl<T: ToString> Mapper<T> for Collector {
type Output = ();
fn map(&mut self, value: &T) -> Self::Output {
self.0.push(format!(
"{} : {}",
std::any::type_name::<T>(),
value.to_string()
))
}
}
impl Mapper<MyElement> for Collector {
type Output = ();
fn map(&mut self, value: &MyElement) -> Self::Output {
self.0.push(format!("MyElement : {}", value.0))
}
}
let mut collector = Collector::default();
tuple!(1, "hello", MyElement(14)).foreach(&mut collector);
assert_eq!(
collector.0,
vec![
"i32 : 1".to_string(),
"&str : hello".to_string(),
"MyElement : 14".to_string()
]
);