1use std::{
4 fmt::Display,
5 io::{self, BufWriter, Write},
6};
7
8#[inline]
29pub fn display_buffered<I, T, W>(values: I, writer: W) -> Result<(), io::Error>
30where
31 T: Display,
32 I: IntoIterator<Item = T>,
33 W: Write,
34{
35 let mut writer = BufWriter::new(writer);
36
37 for value in values {
38 writeln!(writer, "{value}")?
39 }
40
41 writer.flush()
42}
43
44#[inline]
67pub fn write_buffered<T, I, W>(values: I, writer: W) -> Result<(), io::Error>
68where
69 T: AsRef<[u8]>,
70 I: IntoIterator<Item = T>,
71 W: Write,
72{
73 let mut writer = BufWriter::new(writer);
74
75 for bytes in values {
76 writer.write_all(bytes.as_ref())?
77 }
78
79 writer.flush()
80}
81
82#[inline]
106pub fn write_buffered_separated<T, I, W>(
107 values: I,
108 mut writer: W,
109 sep: &[u8],
110) -> Result<(), io::Error>
111where
112 T: AsRef<[u8]>,
113 I: IntoIterator<Item = T>,
114 W: Write,
115{
116 let mut values = values.into_iter();
117 let mut buf_writer;
119 match values.next() {
120 Some(val) => {
121 buf_writer = BufWriter::new(writer);
122 buf_writer.write_all(val.as_ref())?
123 }
124 None => return writer.flush(),
125 }
126
127 for bytes in values {
128 buf_writer.write_all(sep)?;
129 buf_writer.write_all(bytes.as_ref())?
130 }
131
132 buf_writer.flush()
133}
134
135#[inline]
165pub fn write_buffered_separated_with<T, I, W, U, F>(
166 values: I,
167 mut writer: W,
168 mut f: F,
169) -> Result<(), io::Error>
170where
171 T: AsRef<[u8]>,
172 I: IntoIterator<Item = T>,
173 W: Write,
174 U: AsRef<[u8]>,
175 F: FnMut(usize, &[u8]) -> U,
176{
177 let mut values = values.into_iter().enumerate();
178 let mut buf_writer;
180 match values.next() {
181 Some((_, val)) => {
182 buf_writer = BufWriter::new(writer);
183 buf_writer.write_all(val.as_ref())?
184 }
185 None => return writer.flush(),
186 }
187
188 for (pos, bytes) in values {
189 let bytes = bytes.as_ref();
190 buf_writer.write_all(f(pos, bytes).as_ref())?;
191 buf_writer.write_all(bytes)?
192 }
193
194 buf_writer.flush()
195}
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200
201 struct Writer(Vec<u8>);
203
204 impl Writer {
205 fn new() -> Self {
206 Self(Vec::new())
207 }
208
209 fn into_inner(self) -> Vec<u8> {
210 self.0
211 }
212 }
213
214 impl Write for Writer {
215 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
216 self.0.extend(buf);
217 Ok(buf.len())
218 }
219
220 fn flush(&mut self) -> io::Result<()> {
221 Ok(())
222 }
223 }
224
225 #[test]
226 fn test_display_buffered() {
227 let mut writer = Writer::new();
228 display_buffered([10, 20], &mut writer).unwrap();
229 assert_eq!(writer.into_inner(), b"10\n20\n")
230 }
231
232 #[test]
233 fn test_write_buffered_with_slices() {
234 let mut writer = Writer::new();
235 write_buffered(["It ", "Works"], &mut writer).unwrap();
236 assert_eq!(writer.into_inner(), b"It Works")
237 }
238
239 #[test]
240 fn test_write_buffered_with_strings() {
241 let mut writer = Writer::new();
242 write_buffered(["It ".to_owned(), "Works".to_owned()], &mut writer).unwrap();
243 assert_eq!(writer.into_inner(), b"It Works")
244 }
245
246 #[test]
247 fn test_write_buffered_with_bytes() {
248 let mut writer = Writer::new();
249 let values: [&[u8]; 2] = [b"It ", b"Works"];
250 write_buffered(values, &mut writer).unwrap();
251 assert_eq!(writer.into_inner(), b"It Works")
252 }
253
254 #[test]
255 fn test_write_buffered_with_separator() {
256 let mut writer = Writer::new();
257 write_buffered_separated(["It", "Just", "Works"], &mut writer, b" ").unwrap();
258 assert_eq!(writer.into_inner(), b"It Just Works")
259 }
260
261 #[test]
262 fn test_write_buffered_separated_with() {
263 let mut writer = Writer::new();
264 write_buffered_separated_with(["It", "Just", "Works"], &mut writer, |i, _| {
265 if i % 2 == 0 {
266 b"_"
267 } else {
268 b"-"
269 }
270 })
271 .unwrap();
272 assert_eq!(writer.into_inner(), b"It-Just_Works")
273 }
274
275 #[test]
276 fn test_write_buffered_separated_with2() {
277 let mut writer = Writer::new();
278 write_buffered_separated_with(["It", "Just ", "Works_"], &mut writer, |_, val| {
279 if val.len() % 2 == 0 {
280 b"_"
281 } else {
282 b"-"
283 }
284 })
285 .unwrap();
286 assert_eq!(writer.into_inner(), b"It-Just _Works_")
287 }
288}