write_into/
sequence.rs

1use super::{write_into, WriteInto};
2use std::io;
3use std::iter::{ExactSizeIterator, IntoIterator};
4
5/// Used to write values from [`IntoIterator`].
6///
7/// # Example
8///
9/// ```
10/// use write_into::{BigEndian, Sequence, write_into};
11///
12/// let mut buffer = Vec::new();
13/// let written = write_into(&mut buffer, Sequence(&[
14///     BigEndian(0xAABBu16),
15///     BigEndian(0xCCDDu16),
16/// ])).unwrap();
17/// assert_eq!(written, 2);
18/// assert_eq!(&buffer, &[0xAA, 0xBB, 0xCC, 0xDD]);
19/// ```
20pub struct Sequence<T>(pub T)
21where
22    T: IntoIterator,
23    T::Item: WriteInto;
24
25/// Returns how many items was written.
26impl<T> WriteInto for Sequence<T>
27where
28    T: IntoIterator,
29    T::Item: WriteInto,
30{
31    type Output = usize;
32
33    fn write_into(self, sink: &mut impl io::Write) -> io::Result<usize> {
34        let mut written = 0;
35        for item in self.0 {
36            write_into(sink, item)?;
37            written += 1;
38        }
39
40        Ok(written)
41    }
42}
43
44/// Returns how many items was written.
45impl<T> WriteInto for &Sequence<T>
46where
47    T: Copy + IntoIterator,
48    T::Item: WriteInto,
49{
50    type Output = usize;
51
52    fn write_into(self, sink: &mut impl io::Write) -> io::Result<Self::Output> {
53        write_into(sink, Sequence(self.0))
54    }
55}
56
57/// Used to write values from [`IntoIterator`] with known size.
58///
59/// # Example
60///
61/// ```
62/// use write_into::{BigEndian, SizedSequence, write_into};
63///
64/// let mut buffer = Vec::new();
65/// let written = write_into(&mut buffer, SizedSequence(|size| BigEndian(size as u16), &[
66///     BigEndian(0xAABBu16),
67///     BigEndian(0xCCDDu16),
68/// ])).unwrap();
69/// assert_eq!(written, 2);
70/// assert_eq!(&buffer, &[0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xDD]);
71/// ```
72pub struct SizedSequence<T, S, F>(pub F, pub T)
73where
74    T: IntoIterator,
75    T::Item: WriteInto,
76    T::IntoIter: ExactSizeIterator,
77    S: WriteInto,
78    F: FnOnce(usize) -> S;
79
80/// Returns how many items was written.
81impl<T, S, F> WriteInto for SizedSequence<T, S, F>
82where
83    T: IntoIterator,
84    T::Item: WriteInto,
85    T::IntoIter: ExactSizeIterator,
86    S: WriteInto,
87    F: FnOnce(usize) -> S,
88{
89    type Output = usize;
90
91    fn write_into(self, sink: &mut impl io::Write) -> io::Result<Self::Output> {
92        let iterator = self.1.into_iter();
93        let size = iterator.len();
94
95        write_into(sink, (self.0)(size))?;
96        let mut written = 0;
97        for item in iterator {
98            write_into(sink, item)?;
99            written += 1;
100        }
101
102        Ok(written)
103    }
104}
105
106/// Returns how many items was written.
107impl<T, S, F> WriteInto for &SizedSequence<T, S, F>
108where
109    T: Copy + IntoIterator,
110    T::Item: WriteInto,
111    T::IntoIter: ExactSizeIterator,
112    S: WriteInto,
113    F: Copy + FnOnce(usize) -> S,
114{
115    type Output = usize;
116
117    fn write_into(self, sink: &mut impl io::Write) -> io::Result<Self::Output> {
118        write_into(sink, SizedSequence(self.0, self.1))
119    }
120}