cookie_factory/multi.rs
1//! serializers working on a list of elements (vectors, iterators, etc)
2use crate::internal::{SerializeFn, WriteContext};
3use crate::lib::std::io::Write;
4
5/// Applies an iterator of serializers of the same type
6///
7/// ```rust
8/// use cookie_factory::{gen, multi::all, combinator::string};
9///
10/// let mut buf = [0u8; 100];
11///
12/// let data = vec!["abcd", "efgh", "ijkl"];
13/// {
14/// let (buf, pos) = gen(all(data.iter().map(string)), &mut buf[..]).unwrap();
15/// assert_eq!(pos, 12);
16/// assert_eq!(buf.len(), 100 - 12);
17/// }
18///
19/// assert_eq!(&buf[..12], &b"abcdefghijkl"[..]);
20/// ```
21pub fn all<G, W: Write, It>(values: It) -> impl SerializeFn<W>
22where
23 G: SerializeFn<W>,
24 It: Clone + Iterator<Item = G>,
25{
26 move |mut out: WriteContext<W>| {
27 let it = values.clone();
28
29 for v in it {
30 out = v(out)?;
31 }
32
33 Ok(out)
34 }
35}
36
37/// Applies an iterator of serializers of the same type with a separator between each serializer
38///
39/// ```rust
40/// use cookie_factory::{gen, multi::separated_list, combinator::string};
41///
42/// let mut buf = [0u8; 100];
43///
44/// let data = vec!["abcd", "efgh", "ijkl"];
45/// {
46/// let (buf, pos) = gen(separated_list(string(","), data.iter().map(string)), &mut buf[..]).unwrap();
47/// assert_eq!(pos, 14);
48/// assert_eq!(buf.len(), 100 - 14);
49/// }
50///
51/// assert_eq!(&buf[..14], &b"abcd,efgh,ijkl"[..]);
52/// ```
53pub fn separated_list<F, G, W: Write, It>(sep: F, values: It) -> impl SerializeFn<W>
54where
55 F: SerializeFn<W>,
56 G: SerializeFn<W>,
57 It: Clone + Iterator<Item = G>,
58{
59 move |mut out: WriteContext<W>| {
60 let mut it = values.clone();
61
62 match it.next() {
63 None => return Ok(out),
64 Some(first) => {
65 out = first(out)?;
66 }
67 }
68
69 for v in it {
70 out = sep(out).and_then(v)?;
71 }
72
73 Ok(out)
74 }
75}
76
77/// Applies a generator over an iterator of values, and applies the serializers generated
78///
79/// ```rust
80/// use cookie_factory::{gen, multi::many_ref, combinator::string};
81///
82/// let mut buf = [0u8; 100];
83///
84/// let data = vec!["abcd", "efgh", "ijkl"];
85/// {
86/// let (buf, pos) = gen(many_ref(&data, string), &mut buf[..]).unwrap();
87/// assert_eq!(pos, 12);
88/// assert_eq!(buf.len(), 100 - 12);
89/// }
90///
91/// assert_eq!(&buf[..12], &b"abcdefghijkl"[..]);
92/// ```
93pub fn many_ref<E, It, I, F, G, O: Write>(items: I, generator: F) -> impl SerializeFn<O>
94where
95 It: Iterator<Item = E> + Clone,
96 I: IntoIterator<Item = E, IntoIter = It>,
97 F: Fn(E) -> G,
98 G: SerializeFn<O>,
99{
100 let items = items.into_iter();
101 move |mut out: WriteContext<O>| {
102 for item in items.clone() {
103 out = generator(item)(out)?;
104 }
105 Ok(out)
106 }
107}