Skip to main content

rkyv/ser/writer/
std.rs

1use std::io;
2
3use rancor::{ResultExt as _, Source};
4
5use crate::ser::{Positional, Writer};
6
7/// Wraps a type that implements [`io::Write`](std::io::Write) and equips it
8/// with [`Writer`].
9///
10/// # Examples
11/// ```
12/// # use rkyv::ser::{Writer, Positional, writer::IoWriter};
13/// use rkyv::rancor::{Error, Strategy};
14/// let mut io_writer = IoWriter::new(Vec::new());
15/// // In most cases, calling a method like `serialize` will wrap the writer in
16/// // a Strategy for us.
17/// let mut writer = Strategy::<_, Error>::wrap(&mut io_writer);
18/// assert_eq!(writer.pos(), 0);
19/// writer.write(&[0u8, 1u8, 2u8, 3u8]);
20/// assert_eq!(writer.pos(), 4);
21/// let buf = io_writer.into_inner();
22/// assert_eq!(buf.len(), 4);
23/// assert_eq!(buf, vec![0u8, 1u8, 2u8, 3u8]);
24/// ```
25#[derive(Debug)]
26pub struct IoWriter<W> {
27    inner: W,
28    pos: usize,
29}
30
31impl<W> IoWriter<W> {
32    /// Creates a new serializer from a writer.
33    pub fn new(inner: W) -> Self {
34        Self::with_pos(inner, 0)
35    }
36
37    /// Creates a new serializer from a writer, and assumes that the underlying
38    /// writer is currently at the given position.
39    pub fn with_pos(inner: W, pos: usize) -> Self {
40        Self { inner, pos }
41    }
42
43    /// Consumes the serializer and returns the internal writer used to create
44    /// it.
45    pub fn into_inner(self) -> W {
46        self.inner
47    }
48}
49
50impl<W> Positional for IoWriter<W> {
51    fn pos(&self) -> usize {
52        self.pos
53    }
54}
55
56impl<W: io::Write, E: Source> Writer<E> for IoWriter<W> {
57    fn write(&mut self, bytes: &[u8]) -> Result<(), E> {
58        self.inner.write_all(bytes).into_error()?;
59        self.pos += bytes.len();
60        Ok(())
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use rancor::Failure;
67
68    use crate::{
69        api::serialize_using, ser::writer::IoWriter, util::Align, Archive,
70        Serialize,
71    };
72
73    #[test]
74    fn write_serializer() {
75        #[derive(Archive, Serialize)]
76        #[rkyv(crate, attr(repr(C)))]
77        struct Example {
78            x: i32,
79        }
80
81        let mut buf = Align([0u8; 3]);
82        let mut ser = IoWriter::new(&mut buf[..]);
83        let foo = Example { x: 100 };
84        serialize_using::<_, Failure>(&foo, &mut ser)
85            .expect_err("serialized to an undersized buffer must fail");
86    }
87}