bitcoin_consensus_encoding/decode/
mod.rs1pub mod decoders;
6
7pub trait Decodable {
12 type Decoder: Decoder<Output = Self>;
14 fn decoder() -> Self::Decoder;
16}
17
18pub trait Decoder: Sized {
20 type Output;
22 type Error;
24
25 #[must_use = "must check result to avoid panics on subsequent calls"]
43 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error>;
44
45 #[must_use = "must check result to avoid panics on subsequent calls"]
60 fn end(self) -> Result<Self::Output, Self::Error>;
61
62 fn read_limit(&self) -> usize;
68}
69
70pub fn decode_from_slice<T>(bytes: &[u8]) -> Result<T, <T::Decoder as Decoder>::Error>
77where
78 T: Decodable,
79{
80 let mut decoder = T::decoder();
81 let mut remaining = bytes;
82
83 while !remaining.is_empty() {
84 if !decoder.push_bytes(&mut remaining)? {
85 break;
86 }
87 }
88
89 decoder.end()
90}
91
92#[cfg(feature = "std")]
106pub fn decode_from_read<T, R>(mut reader: R) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
107where
108 T: Decodable,
109 R: std::io::BufRead,
110{
111 let mut decoder = T::decoder();
112
113 loop {
114 let mut buffer = match reader.fill_buf() {
115 Ok(buffer) => buffer,
116 Err(error) if error.kind() == std::io::ErrorKind::Interrupted => continue,
118 Err(error) => return Err(ReadError::Io(error)),
119 };
120
121 if buffer.is_empty() {
122 return decoder.end().map_err(ReadError::Decode);
124 }
125
126 let original_len = buffer.len();
127 let need_more = decoder.push_bytes(&mut buffer).map_err(ReadError::Decode)?;
128 let consumed = original_len - buffer.len();
129 reader.consume(consumed);
130
131 if !need_more {
132 return decoder.end().map_err(ReadError::Decode);
133 }
134 }
135}
136
137#[cfg(feature = "std")]
156pub fn decode_from_read_unbuffered<T, R>(
157 reader: R,
158) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
159where
160 T: Decodable,
161 R: std::io::Read,
162{
163 decode_from_read_unbuffered_with::<T, R, 4096>(reader)
164}
165
166#[cfg(feature = "std")]
184pub fn decode_from_read_unbuffered_with<T, R, const BUFFER_SIZE: usize>(
185 mut reader: R,
186) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
187where
188 T: Decodable,
189 R: std::io::Read,
190{
191 let mut decoder = T::decoder();
192 let mut buffer = [0u8; BUFFER_SIZE];
193
194 while decoder.read_limit() > 0 {
195 let clamped_buffer = &mut buffer[..decoder.read_limit().min(BUFFER_SIZE)];
197 match reader.read(clamped_buffer) {
198 Ok(0) => {
199 return decoder.end().map_err(ReadError::Decode);
201 }
202 Ok(bytes_read) => {
203 if !decoder
204 .push_bytes(&mut &clamped_buffer[..bytes_read])
205 .map_err(ReadError::Decode)?
206 {
207 return decoder.end().map_err(ReadError::Decode);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {
211 }
213 Err(e) => return Err(ReadError::Io(e)),
214 }
215 }
216
217 decoder.end().map_err(ReadError::Decode)
218}
219
220#[cfg(feature = "std")]
222#[derive(Debug)]
223pub enum ReadError<D> {
224 Io(std::io::Error),
226 Decode(D),
228}
229
230#[cfg(feature = "std")]
231impl<D: core::fmt::Display> core::fmt::Display for ReadError<D> {
232 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
233 match self {
234 Self::Io(e) => write!(f, "I/O error: {}", e),
235 Self::Decode(e) => write!(f, "decode error: {}", e),
236 }
237 }
238}
239
240#[cfg(feature = "std")]
241impl<D> std::error::Error for ReadError<D>
242where
243 D: core::fmt::Debug + core::fmt::Display + std::error::Error + 'static,
244{
245 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
246 match self {
247 Self::Io(e) => Some(e),
248 Self::Decode(e) => Some(e),
249 }
250 }
251}
252
253#[cfg(feature = "std")]
254impl<D> From<std::io::Error> for ReadError<D> {
255 fn from(e: std::io::Error) -> Self { Self::Io(e) }
256}
257
258#[cfg(test)]
259mod tests {
260 #[cfg(feature = "std")]
261 use alloc::vec::Vec;
262 #[cfg(feature = "std")]
263 use std::io::{Cursor, Read};
264
265 use super::*;
266 use crate::decode::decoders::{ArrayDecoder, UnexpectedEofError};
267
268 #[derive(Debug, PartialEq)]
269 struct TestArray([u8; 4]);
270
271 impl Decodable for TestArray {
272 type Decoder = TestArrayDecoder;
273 fn decoder() -> Self::Decoder { TestArrayDecoder { inner: ArrayDecoder::new() } }
274 }
275
276 struct TestArrayDecoder {
277 inner: ArrayDecoder<4>,
278 }
279
280 impl Decoder for TestArrayDecoder {
281 type Output = TestArray;
282 type Error = UnexpectedEofError;
283
284 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
285 self.inner.push_bytes(bytes)
286 }
287
288 fn end(self) -> Result<Self::Output, Self::Error> { self.inner.end().map(TestArray) }
289
290 fn read_limit(&self) -> usize { self.inner.read_limit() }
291 }
292
293 #[test]
294 fn decode_from_slice_success() {
295 let data = [1, 2, 3, 4];
296 let result: Result<TestArray, _> = decode_from_slice(&data);
297 assert!(result.is_ok());
298 let decoded = result.unwrap();
299 assert_eq!(decoded.0, [1, 2, 3, 4]);
300 }
301
302 #[test]
303 fn decode_from_slice_unexpected_eof() {
304 let data = [1, 2, 3];
305 let result: Result<TestArray, _> = decode_from_slice(&data);
306 assert!(result.is_err());
307 }
308
309 #[test]
310 fn decode_from_slice_extra_data() {
311 let data = [1, 2, 3, 4, 5];
312 let result: Result<TestArray, _> = decode_from_slice(&data);
313 assert!(result.is_ok());
314 let decoded = result.unwrap();
315 assert_eq!(decoded.0, [1, 2, 3, 4]);
316 }
317
318 #[cfg(feature = "std")]
319 #[test]
320 fn decode_from_read_extra_data() {
321 let data = [1, 2, 3, 4, 5, 6];
322 let mut cursor = Cursor::new(&data);
323 let result: Result<TestArray, _> = decode_from_read(&mut cursor);
324 assert!(result.is_ok());
325 let decoded = result.unwrap();
326 assert_eq!(decoded.0, [1, 2, 3, 4]);
327 }
328
329 #[cfg(feature = "std")]
330 #[test]
331 fn decode_from_read_success() {
332 let data = [1, 2, 3, 4];
333 let cursor = Cursor::new(&data);
334 let result: Result<TestArray, _> = decode_from_read(cursor);
335 assert!(result.is_ok());
336 let decoded = result.unwrap();
337 assert_eq!(decoded.0, [1, 2, 3, 4]);
338 }
339
340 #[cfg(feature = "std")]
341 #[test]
342 fn decode_from_read_unexpected_eof() {
343 let data = [1, 2, 3];
344 let cursor = Cursor::new(&data);
345 let result: Result<TestArray, _> = decode_from_read(cursor);
346 assert!(matches!(result, Err(ReadError::Decode(_))));
347 }
348
349 #[cfg(feature = "std")]
350 #[test]
351 fn decode_from_read_trait_object() {
352 let data = [1, 2, 3, 4];
353 let mut cursor = Cursor::new(&data);
354 let reader: &mut dyn std::io::BufRead = &mut cursor;
356 let result: Result<TestArray, _> = decode_from_read(reader);
357 assert!(result.is_ok());
358 let decoded = result.unwrap();
359 assert_eq!(decoded.0, [1, 2, 3, 4]);
360 }
361
362 #[cfg(feature = "std")]
363 #[test]
364 fn decode_from_read_by_reference() {
365 let data = [1, 2, 3, 4];
366 let mut cursor = Cursor::new(&data);
367 let result: Result<TestArray, _> = decode_from_read(&mut cursor);
369 assert!(result.is_ok());
370 let decoded = result.unwrap();
371 assert_eq!(decoded.0, [1, 2, 3, 4]);
372
373 let mut buf = Vec::new();
374 let _ = cursor.read_to_end(&mut buf);
375 }
376
377 #[cfg(feature = "std")]
378 #[test]
379 fn decode_from_read_unbuffered_success() {
380 let data = [1, 2, 3, 4];
381 let cursor = Cursor::new(&data);
382 let result: Result<TestArray, _> = decode_from_read_unbuffered(cursor);
383 assert!(result.is_ok());
384 let decoded = result.unwrap();
385 assert_eq!(decoded.0, [1, 2, 3, 4]);
386 }
387
388 #[cfg(feature = "std")]
389 #[test]
390 fn decode_from_read_unbuffered_unexpected_eof() {
391 let data = [1, 2, 3];
392 let cursor = Cursor::new(&data);
393 let result: Result<TestArray, _> = decode_from_read_unbuffered(cursor);
394 assert!(matches!(result, Err(ReadError::Decode(_))));
395 }
396
397 #[cfg(feature = "std")]
398 #[test]
399 fn decode_from_read_unbuffered_empty() {
400 let data = [];
401 let cursor = Cursor::new(&data);
402 let result: Result<TestArray, _> = decode_from_read_unbuffered(cursor);
403 assert!(matches!(result, Err(ReadError::Decode(_))));
404 }
405
406 #[cfg(feature = "std")]
407 #[test]
408 fn decode_from_read_unbuffered_extra_data() {
409 let data = [1, 2, 3, 4, 5, 6];
410 let cursor = Cursor::new(&data);
411 let result: Result<TestArray, _> = decode_from_read_unbuffered(cursor);
412 assert!(result.is_ok());
413 let decoded = result.unwrap();
414 assert_eq!(decoded.0, [1, 2, 3, 4]);
415 }
416}