musli_common/
buffered_writer.rs

1//! A writer which buffers the writes before it outputs it into the backing
2//! storage.
3
4use musli::{Buf, Context};
5
6use crate::fixed::FixedBytes;
7use crate::writer::Writer;
8
9/// A writer which buffers `N` bytes inline.
10///
11/// Once you're done you must call [BufferedWriter::finish] to flush the
12/// underlying buffer.
13pub struct BufferedWriter<const N: usize, W> {
14    buf: FixedBytes<N>,
15    writer: W,
16}
17
18impl<const N: usize, W> BufferedWriter<N, W>
19where
20    W: Writer,
21{
22    /// Construct a new buffered writer.
23    pub fn new(writer: W) -> Self {
24        Self {
25            buf: FixedBytes::new(),
26            writer,
27        }
28    }
29
30    /// Finish writing.
31    pub fn finish<C>(mut self, cx: &C) -> Result<(), C::Error>
32    where
33        C: ?Sized + Context,
34    {
35        if !self.buf.is_empty() {
36            self.writer.write_bytes(cx, self.buf.as_slice())?;
37        }
38
39        Ok(())
40    }
41}
42
43impl<const N: usize, W> Writer for BufferedWriter<N, W>
44where
45    W: Writer,
46{
47    type Mut<'this> = &'this mut Self where Self: 'this;
48
49    #[inline]
50    fn borrow_mut(&mut self) -> Self::Mut<'_> {
51        self
52    }
53
54    #[inline]
55    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
56    where
57        C: ?Sized + Context,
58        B: Buf,
59    {
60        // SAFETY: the buffer never outlives this function call.
61        self.write_bytes(cx, buffer.as_slice())
62    }
63
64    #[inline]
65    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
66    where
67        C: ?Sized + Context,
68    {
69        if self.buf.remaining() < bytes.len() {
70            self.writer.write_bytes(cx, self.buf.as_slice())?;
71            self.buf.clear();
72        }
73
74        self.buf.write_bytes(cx, bytes)
75    }
76}