Coverage Report

Created: 2025-10-10 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bincode-1.3.3/src/de/read.rs
Line
Count
Source
1
use error::Result;
2
use serde;
3
use std::io;
4
5
/// An optional Read trait for advanced Bincode usage.
6
///
7
/// It is highly recommended to use bincode with `io::Read` or `&[u8]` before
8
/// implementing a custom `BincodeRead`.
9
///
10
/// The forward_read_* methods are necessary because some byte sources want
11
/// to pass a long-lived borrow to the visitor and others want to pass a
12
/// transient slice.
13
pub trait BincodeRead<'storage>: io::Read {
14
    /// Check that the next `length` bytes are a valid string and pass
15
    /// it on to the serde reader.
16
    fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
17
    where
18
        V: serde::de::Visitor<'storage>;
19
20
    /// Transfer ownership of the next `length` bytes to the caller.
21
    fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>>;
22
23
    /// Pass a slice of the next `length` bytes on to the serde reader.
24
    fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
25
    where
26
        V: serde::de::Visitor<'storage>;
27
}
28
29
/// A BincodeRead implementation for byte slices
30
pub struct SliceReader<'storage> {
31
    slice: &'storage [u8],
32
}
33
34
/// A BincodeRead implementation for `io::Read`ers
35
pub struct IoReader<R> {
36
    reader: R,
37
    temp_buffer: Vec<u8>,
38
}
39
40
impl<'storage> SliceReader<'storage> {
41
    /// Constructs a slice reader
42
0
    pub(crate) fn new(bytes: &'storage [u8]) -> SliceReader<'storage> {
43
0
        SliceReader { slice: bytes }
44
0
    }
45
46
    #[inline(always)]
47
0
    fn get_byte_slice(&mut self, length: usize) -> Result<&'storage [u8]> {
48
0
        if length > self.slice.len() {
49
0
            return Err(SliceReader::unexpected_eof());
50
0
        }
51
0
        let (read_slice, remaining) = self.slice.split_at(length);
52
0
        self.slice = remaining;
53
0
        Ok(read_slice)
54
0
    }
55
56
0
    pub(crate) fn is_finished(&self) -> bool {
57
0
        self.slice.is_empty()
58
0
    }
59
}
60
61
impl<R> IoReader<R> {
62
    /// Constructs an IoReadReader
63
4.68k
    pub(crate) fn new(r: R) -> IoReader<R> {
64
4.68k
        IoReader {
65
4.68k
            reader: r,
66
4.68k
            temp_buffer: vec![],
67
4.68k
        }
68
4.68k
    }
<bincode::de::read::IoReader<&[u8]>>::new
Line
Count
Source
63
4.68k
    pub(crate) fn new(r: R) -> IoReader<R> {
64
4.68k
        IoReader {
65
4.68k
            reader: r,
66
4.68k
            temp_buffer: vec![],
67
4.68k
        }
68
4.68k
    }
Unexecuted instantiation: <bincode::de::read::IoReader<_>>::new
69
}
70
71
impl<'storage> io::Read for SliceReader<'storage> {
72
    #[inline(always)]
73
0
    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
74
0
        if out.len() > self.slice.len() {
75
0
            return Err(io::ErrorKind::UnexpectedEof.into());
76
0
        }
77
0
        let (read_slice, remaining) = self.slice.split_at(out.len());
78
0
        out.copy_from_slice(read_slice);
79
0
        self.slice = remaining;
80
0
81
0
        Ok(out.len())
82
0
    }
83
84
    #[inline(always)]
85
0
    fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> {
86
0
        self.read(out).map(|_| ())
87
0
    }
88
}
89
90
impl<R: io::Read> io::Read for IoReader<R> {
91
    #[inline(always)]
92
0
    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
93
0
        self.reader.read(out)
94
0
    }
95
    #[inline(always)]
96
154k
    fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> {
97
154k
        self.reader.read_exact(out)
98
154k
    }
<bincode::de::read::IoReader<&[u8]> as std::io::Read>::read_exact
Line
Count
Source
96
154k
    fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> {
97
154k
        self.reader.read_exact(out)
98
154k
    }
Unexecuted instantiation: <bincode::de::read::IoReader<_> as std::io::Read>::read_exact
99
}
100
101
impl<'storage> SliceReader<'storage> {
102
    #[inline(always)]
103
0
    fn unexpected_eof() -> Box<::ErrorKind> {
104
0
        Box::new(::ErrorKind::Io(io::Error::new(
105
0
            io::ErrorKind::UnexpectedEof,
106
0
            "",
107
0
        )))
108
0
    }
109
}
110
111
impl<'storage> BincodeRead<'storage> for SliceReader<'storage> {
112
    #[inline(always)]
113
0
    fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
114
0
    where
115
0
        V: serde::de::Visitor<'storage>,
116
0
    {
117
        use ErrorKind;
118
0
        let string = match ::std::str::from_utf8(self.get_byte_slice(length)?) {
119
0
            Ok(s) => s,
120
0
            Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()),
121
        };
122
0
        visitor.visit_borrowed_str(string)
123
0
    }
124
125
    #[inline(always)]
126
0
    fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
127
0
        self.get_byte_slice(length).map(|x| x.to_vec())
128
0
    }
129
130
    #[inline(always)]
131
0
    fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
132
0
    where
133
0
        V: serde::de::Visitor<'storage>,
134
0
    {
135
0
        visitor.visit_borrowed_bytes(self.get_byte_slice(length)?)
136
0
    }
137
}
138
139
impl<R> IoReader<R>
140
where
141
    R: io::Read,
142
{
143
2.01k
    fn fill_buffer(&mut self, length: usize) -> Result<()> {
144
2.01k
        self.temp_buffer.resize(length, 0);
145
2.01k
146
2.01k
        self.reader.read_exact(&mut self.temp_buffer)?;
147
148
1.97k
        Ok(())
149
2.01k
    }
<bincode::de::read::IoReader<&[u8]>>::fill_buffer
Line
Count
Source
143
2.01k
    fn fill_buffer(&mut self, length: usize) -> Result<()> {
144
2.01k
        self.temp_buffer.resize(length, 0);
145
2.01k
146
2.01k
        self.reader.read_exact(&mut self.temp_buffer)?;
147
148
1.97k
        Ok(())
149
2.01k
    }
Unexecuted instantiation: <bincode::de::read::IoReader<_>>::fill_buffer
150
}
151
152
impl<'a, R> BincodeRead<'a> for IoReader<R>
153
where
154
    R: io::Read,
155
{
156
0
    fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
157
0
    where
158
0
        V: serde::de::Visitor<'a>,
159
0
    {
160
0
        self.fill_buffer(length)?;
161
162
0
        let string = match ::std::str::from_utf8(&self.temp_buffer[..]) {
163
0
            Ok(s) => s,
164
0
            Err(e) => return Err(::ErrorKind::InvalidUtf8Encoding(e).into()),
165
        };
166
167
0
        visitor.visit_str(string)
168
0
    }
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::socket_addr::SocketAddr>>
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::socket_addr::SocketAddrV4>>
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::socket_addr::SocketAddrV6>>
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::ip_addr::IpAddr>>
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::ip_addr::Ipv4Addr>>
Unexecuted instantiation: <bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::forward_read_str::<serde::de::impls::FromStrVisitor<core::net::ip_addr::Ipv6Addr>>
Unexecuted instantiation: <bincode::de::read::IoReader<_> as bincode::de::read::BincodeRead>::forward_read_str::<_>
169
170
2.01k
    fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
171
2.01k
        self.fill_buffer(length)?;
172
1.97k
        Ok(::std::mem::replace(&mut self.temp_buffer, Vec::new()))
173
2.01k
    }
<bincode::de::read::IoReader<&[u8]> as bincode::de::read::BincodeRead>::get_byte_buffer
Line
Count
Source
170
2.01k
    fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> {
171
2.01k
        self.fill_buffer(length)?;
172
1.97k
        Ok(::std::mem::replace(&mut self.temp_buffer, Vec::new()))
173
2.01k
    }
Unexecuted instantiation: <bincode::de::read::IoReader<_> as bincode::de::read::BincodeRead>::get_byte_buffer
174
175
0
    fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value>
176
0
    where
177
0
        V: serde::de::Visitor<'a>,
178
0
    {
179
0
        self.fill_buffer(length)?;
180
0
        visitor.visit_bytes(&self.temp_buffer[..])
181
0
    }
182
}
183
184
#[cfg(test)]
185
mod test {
186
    use super::IoReader;
187
188
    #[test]
189
    fn test_fill_buffer() {
190
        let buffer = vec![0u8; 64];
191
        let mut reader = IoReader::new(buffer.as_slice());
192
193
        reader.fill_buffer(20).unwrap();
194
        assert_eq!(20, reader.temp_buffer.len());
195
196
        reader.fill_buffer(30).unwrap();
197
        assert_eq!(30, reader.temp_buffer.len());
198
199
        reader.fill_buffer(5).unwrap();
200
        assert_eq!(5, reader.temp_buffer.len());
201
    }
202
}