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