pod/
io.rs

1use std::io;
2use pod::Pod;
3
4#[cfg(feature = "uninitialized")]
5use uninitialized::uninitialized;
6#[cfg(not(feature = "uninitialized"))]
7use std::mem::zeroed as uninitialized;
8
9#[cfg(feature = "read_exact")]
10use read_exact::ReadExactExt;
11
12/// An extension trait for reading `Pod` types from `std::io::Read` data streams.
13pub trait PodReadExt {
14    /// Reads a `Pod` struct from the stream. Behaves like `read_exact`, and will
15    /// produce an error if EOF is encountered before the data is fully read.
16    fn read_pod<P: Pod>(&mut self) -> io::Result<P>;
17
18    /// Reads a `Pod` struct from the stream, or nothing at EOF. Partial reads
19    /// will result in an error.
20    #[cfg(feature = "read_exact")]
21    fn read_pod_or_none<P: Pod>(&mut self) -> io::Result<Option<P>>;
22}
23
24impl<T: io::Read> PodReadExt for T {
25    #[inline]
26    fn read_pod<P: Pod>(&mut self) -> io::Result<P> {
27        let mut data: P = unsafe { uninitialized() };
28
29        self.read_exact(data.as_bytes_mut()).map(|_| data)
30    }
31
32    #[inline]
33    #[cfg(feature = "read_exact")]
34    fn read_pod_or_none<P: Pod>(&mut self) -> io::Result<Option<P>> {
35        let mut data: P = unsafe { uninitialized() };
36
37        self.read_exact_or_eof(data.as_bytes_mut()).map(|read| if read {
38            Some(data)
39        } else {
40            None
41        })
42    }
43}
44
45/// An extension trait for writing `Pod` types to `std::io::Write` data streams.
46pub trait PodWriteExt {
47    /// Writes the memory representation of a `Pod` struct to the stream.
48    /// Behaves like `write_all`, failure to write the entire structure will
49    /// result in an error.
50    fn write_pod<P: Pod>(&mut self, data: &P) -> io::Result<()>;
51}
52
53impl<T: io::Write> PodWriteExt for T {
54    #[inline]
55    fn write_pod<P: Pod>(&mut self, data: &P) -> io::Result<()> {
56        self.write_all(data.as_bytes())
57    }
58}