kv_derive_impl/
producer.rs1use std::iter;
2
3use crate::into_vec::IntoVec;
4
5pub trait Producer<T> {
9 type Iter: Iterator<Item = (String, String)>;
10
11 fn produce(self, key: &'static str, value: T) -> Self::Iter;
12}
13
14#[derive(Copy, Clone)]
18pub struct ScalarProducer;
19
20impl<V: ToString> Producer<V> for ScalarProducer {
21 type Iter = iter::Once<(String, String)>;
22
23 #[inline]
24 fn produce(self, key: &'static str, value: V) -> Self::Iter {
25 iter::once((key.to_string(), value.to_string()))
26 }
27}
28
29#[derive(Copy, Clone)]
30pub struct WrappedProducer<P, F>(pub P, pub F);
31
32impl<V1, V2, P: Producer<V2>, F: Fn(V1) -> V2> Producer<V1> for WrappedProducer<P, F> {
33 type Iter = P::Iter;
34
35 #[inline]
36 fn produce(self, key: &'static str, value: V1) -> Self::Iter {
37 self.0.produce(key, self.1(value))
38 }
39}
40
41#[derive(Copy, Clone)]
45pub struct OptionProducer<P>(pub P);
46
47impl<V, P: Producer<V>> Producer<Option<V>> for OptionProducer<P> {
48 type Iter = iter::FlatMap<
49 iter::Zip<iter::Zip<std::option::IntoIter<V>, iter::Once<&'static str>>, iter::Once<P>>,
50 P::Iter,
51 fn(((V, &'static str), P)) -> P::Iter,
52 >;
53
54 #[inline]
55 fn produce(self, key: &'static str, value: Option<V>) -> Self::Iter {
56 value
57 .into_iter()
58 .zip(iter::once(key))
59 .zip(iter::once(self.0))
60 .flat_map(|((value, key), producer)| producer.produce(key, value))
61 }
62}
63
64#[derive(Copy, Clone)]
68pub struct CollectionProducer<P>(pub P);
69
70impl<V, P: Producer<V> + Copy + Clone> Producer<Vec<V>> for CollectionProducer<P> {
71 type Iter = iter::FlatMap<
72 iter::Zip<iter::Zip<iter::Repeat<&'static str>, std::vec::IntoIter<V>>, iter::Repeat<P>>,
73 <P as Producer<V>>::Iter,
74 fn(((&'static str, V), P)) -> <P as Producer<V>>::Iter,
75 >;
76
77 #[inline]
78 fn produce(self, key: &'static str, values: Vec<V>) -> Self::Iter {
79 iter::repeat(key)
80 .zip(values.into_iter())
81 .zip(iter::repeat(self.0))
82 .into_iter()
83 .flat_map(|((key, value), producer)| producer.produce(key, value))
84 }
85}
86
87#[derive(Copy, Clone)]
91pub struct FlatteningProducer;
92
93impl<T: IntoVec> Producer<T> for FlatteningProducer {
94 type Iter = Box<dyn Iterator<Item = (String, String)>>;
95
96 #[inline]
97 fn produce(self, _key: &'static str, value: T) -> Self::Iter {
98 value.into_iter()
99 }
100}
101
102#[derive(Copy, Clone)]
107pub struct PrefixedFlatteningProducer(pub &'static str);
108
109impl<V: IntoVec> Producer<V> for PrefixedFlatteningProducer {
110 type Iter = Box<dyn Iterator<Item = (String, String)>>;
111
112 #[inline]
113 fn produce(self, _key: &'static str, value: V) -> Self::Iter {
114 Box::new(
115 value
116 .into_iter()
117 .map(move |(key, value)| (format!("{}{}", self.0, key), value)),
118 )
119 }
120}