Skip to main content

bitcoin_io/
lib.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Rust Bitcoin I/O Library
4//!
5//! The [`std::io`] module is not exposed in `no-std` Rust so building `no-std` applications which
6//! require reading and writing objects via standard traits is not generally possible. Thus, this
7//! library exists to export a minimal version of `std::io`'s traits which we use in `rust-bitcoin`
8//! so that we can support `no-std` applications.
9//!
10//! These traits are not one-for-one drop-ins, but are as close as possible while still implementing
11//! `std::io`'s traits without unnecessary complexity.
12//!
13//! For examples of how to use and implement the types and traits in this crate see `io.rs` in the
14//! `github.com/rust-bitcoin/rust-bitcoin/bitcoin/examples/` directory.
15
16#![no_std]
17// Coding conventions.
18#![warn(missing_docs)]
19#![doc(test(attr(warn(unused))))]
20// Pedantic lints that we enforce.
21#![warn(clippy::return_self_not_must_use)]
22
23#[cfg(feature = "alloc")]
24extern crate alloc;
25
26#[cfg(feature = "std")]
27extern crate std;
28
29pub extern crate encoding;
30
31#[cfg(feature = "hashes")]
32pub extern crate hashes;
33
34#[cfg(feature = "std")]
35mod bridge;
36pub mod error;
37
38#[cfg(feature = "hashes")]
39mod hash;
40
41#[cfg(feature = "alloc")]
42#[cfg(not(feature = "std"))]
43use alloc::vec::Vec;
44use core::cmp;
45#[cfg(feature = "std")]
46use std::vec::Vec;
47
48use encoding::{Decode, Decoder, Encoder};
49
50#[rustfmt::skip]                // Keep public re-exports separate.
51#[doc(no_inline)]
52pub use self::error::{Error, ErrorKind, ReadError};
53#[cfg(feature = "std")]
54pub use self::bridge::{FromStd, ToStd};
55#[cfg(feature = "hashes")]
56pub use self::hash::hash_reader;
57
58/// Result type returned by functions in this crate.
59pub type Result<T> = core::result::Result<T, Error>;
60
61/// A generic trait describing an input stream.
62///
63/// See [`std::io::Read`] for more information.
64pub trait Read {
65    /// Reads bytes from source into `buf`.
66    ///
67    /// # Returns
68    ///
69    /// The number of bytes read if successful or an [`Error`] if reading fails.
70    ///
71    /// # Errors
72    ///
73    /// If the underlying reader encounters an I/O error.
74    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
75
76    /// Reads bytes from source until `buf` is full.
77    ///
78    /// # Errors
79    ///
80    /// If the exact number of bytes required to fill `buf` cannot be read.
81    #[inline]
82    fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
83        while !buf.is_empty() {
84            match self.read(buf) {
85                Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
86                Ok(len) => buf = &mut buf[len..],
87                Err(e) if e.kind() == ErrorKind::Interrupted => {}
88                Err(e) => return Err(e),
89            }
90        }
91        Ok(())
92    }
93
94    /// Constructs a new adapter which will read at most `limit` bytes.
95    #[inline]
96    fn take(self, limit: u64) -> Take<Self>
97    where
98        Self: Sized,
99    {
100        Take { reader: self, remaining: limit }
101    }
102
103    /// Attempts to read up to limit bytes from the reader, allocating space in `buf` as needed.
104    ///
105    /// `limit` is used to prevent a denial of service attack vector since an unbounded reader will
106    /// exhaust all memory.
107    ///
108    /// Similar to [`std::io::Read::read_to_end`] but with the DOS protection.
109    ///
110    /// # Returns
111    ///
112    /// The number of bytes read if successful or an [`Error`] if reading fails.
113    ///
114    /// # Errors
115    ///
116    /// If an I/O error occurs while reading from the underlying reader.
117    #[doc(alias = "read_to_end")]
118    #[cfg(feature = "alloc")]
119    #[inline]
120    fn read_to_limit(&mut self, buf: &mut Vec<u8>, limit: u64) -> Result<usize> {
121        self.take(limit).read_to_end(buf)
122    }
123}
124
125/// A trait describing an input stream that uses an internal buffer when reading.
126pub trait BufRead: Read {
127    /// Returns data read from this reader, filling the internal buffer if needed.
128    ///
129    /// # Errors
130    ///
131    /// May error if reading fails.
132    fn fill_buf(&mut self) -> Result<&[u8]>;
133
134    /// Marks the buffered data up to amount as consumed.
135    ///
136    /// # Panics
137    ///
138    /// May panic if `amount` is greater than the amount of data read by `fill_buf`.
139    fn consume(&mut self, amount: usize);
140}
141
142/// Reader adapter which limits the bytes read from an underlying reader.
143///
144/// Created by calling `[Read::take]`.
145#[derive(Debug)]
146pub struct Take<R> {
147    reader: R,
148    remaining: u64,
149}
150
151impl<R: Read> Take<R> {
152    /// Reads all bytes until EOF from the underlying reader into `buf`.
153    ///
154    /// Allocates space in `buf` as needed.
155    ///
156    /// # Returns
157    ///
158    /// The number of bytes read if successful or an [`Error`] if reading fails.
159    ///
160    /// # Errors
161    ///
162    /// If an I/O error occurs while reading from the underlying reader.
163    #[cfg(feature = "alloc")]
164    #[inline]
165    pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
166        let mut read: usize = 0;
167        let mut chunk = [0u8; 64];
168        loop {
169            match self.read(&mut chunk) {
170                Ok(0) => break,
171                Ok(n) => {
172                    buf.extend_from_slice(&chunk[0..n]);
173                    read += n;
174                }
175                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
176                Err(e) => return Err(e),
177            };
178        }
179        Ok(read)
180    }
181}
182
183impl<R: Read> Read for Take<R> {
184    #[inline]
185    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
186        let len = cmp::min(buf.len(), self.remaining.try_into().unwrap_or(buf.len()));
187        let read = self.reader.read(&mut buf[..len])?;
188        self.remaining -= read.try_into().unwrap_or(self.remaining);
189        Ok(read)
190    }
191}
192
193// Impl copied from Rust stdlib.
194impl<R: BufRead> BufRead for Take<R> {
195    #[inline]
196    fn fill_buf(&mut self) -> Result<&[u8]> {
197        // Don't call into inner reader at all at EOF because it may still block
198        if self.remaining == 0 {
199            return Ok(&[]);
200        }
201
202        let buf = self.reader.fill_buf()?;
203        // Cast length to a u64 instead of casting `remaining` to a `usize`
204        // (in case `remaining > u32::MAX` and we are on a 32 bit machine).
205        let cap = cmp::min(buf.len() as u64, self.remaining) as usize;
206        Ok(&buf[..cap])
207    }
208
209    #[inline]
210    fn consume(&mut self, amount: usize) {
211        assert!(amount as u64 <= self.remaining);
212        self.remaining -= amount as u64;
213        self.reader.consume(amount);
214    }
215}
216
217impl<T: Read + ?Sized> Read for &'_ mut T {
218    #[inline]
219    fn read(&mut self, buf: &mut [u8]) -> Result<usize> { (**self).read(buf) }
220
221    #[inline]
222    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { (**self).read_exact(buf) }
223}
224
225impl<T: BufRead + ?Sized> BufRead for &'_ mut T {
226    #[inline]
227    fn fill_buf(&mut self) -> Result<&[u8]> { (**self).fill_buf() }
228
229    #[inline]
230    fn consume(&mut self, amount: usize) { (**self).consume(amount) }
231}
232
233impl Read for &[u8] {
234    #[inline]
235    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
236        let cnt = cmp::min(self.len(), buf.len());
237        buf[..cnt].copy_from_slice(&self[..cnt]);
238        *self = &self[cnt..];
239        Ok(cnt)
240    }
241}
242
243impl BufRead for &[u8] {
244    #[inline]
245    fn fill_buf(&mut self) -> Result<&[u8]> { Ok(self) }
246
247    // This panics if amount is out of bounds, same as the std version.
248    #[inline]
249    fn consume(&mut self, amount: usize) { *self = &self[amount..] }
250}
251
252/// Wraps an in memory buffer providing `position` functionality for read and write.
253#[derive(Clone, Debug, Default, Eq, PartialEq)]
254pub struct Cursor<T> {
255    inner: T,
256    pos: u64,
257}
258
259impl<T: AsRef<[u8]>> Cursor<T> {
260    /// Constructs a new `Cursor` by wrapping `inner`.
261    #[inline]
262    pub const fn new(inner: T) -> Self { Self { inner, pos: 0 } }
263
264    /// Returns the position read or written up to thus far.
265    #[inline]
266    pub const fn position(&self) -> u64 { self.pos }
267
268    /// Sets the internal position.
269    ///
270    /// This method allows seeking within the wrapped memory by setting the position.
271    ///
272    /// Note that setting a position that is larger than the buffer length will cause reads to
273    /// succeed by reading zero bytes. Further, writes will be no-op zero length writes.
274    #[inline]
275    pub fn set_position(&mut self, position: u64) { self.pos = position; }
276
277    /// Returns the inner buffer.
278    ///
279    /// This is the whole wrapped buffer, including the bytes already read.
280    #[inline]
281    pub fn into_inner(self) -> T { self.inner }
282
283    /// Returns a reference to the inner buffer.
284    ///
285    /// This is the whole wrapped buffer, including the bytes already read.
286    #[inline]
287    pub const fn get_ref(&self) -> &T { &self.inner }
288
289    /// Returns a mutable reference to the inner buffer.
290    ///
291    /// This is the whole wrapped buffer, including the bytes already read.
292    #[inline]
293    pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
294
295    /// Returns a reference to the inner buffer.
296    ///
297    /// This is the whole wrapped buffer, including the bytes already read.
298    #[inline]
299    #[deprecated(since = "0.3.0", note = "use `get_ref()` instead")]
300    pub fn inner(&self) -> &T { &self.inner }
301}
302
303impl<T: AsRef<[u8]>> Read for Cursor<T> {
304    #[inline]
305    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
306        let inner: &[u8] = self.inner.as_ref();
307        let start_pos = self.pos.try_into().unwrap_or(inner.len());
308        if start_pos >= self.inner.as_ref().len() {
309            return Ok(0);
310        }
311
312        let read = core::cmp::min(inner.len().saturating_sub(start_pos), buf.len());
313        buf[..read].copy_from_slice(&inner[start_pos..start_pos + read]);
314        self.pos = self.pos.saturating_add(read.try_into().unwrap_or(u64::MAX /* unreachable */));
315        Ok(read)
316    }
317}
318
319impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
320    #[inline]
321    fn fill_buf(&mut self) -> Result<&[u8]> {
322        let inner: &[u8] = self.inner.as_ref();
323        let pos = self.pos.min(inner.len() as u64) as usize;
324        Ok(&inner[pos..])
325    }
326
327    #[inline]
328    fn consume(&mut self, amount: usize) { self.pos = self.pos.saturating_add(amount as u64); }
329}
330
331impl<T: AsMut<[u8]>> Write for Cursor<T> {
332    #[inline]
333    fn write(&mut self, buf: &[u8]) -> Result<usize> {
334        let write_slice = self.inner.as_mut();
335        let pos = cmp::min(self.pos, write_slice.len() as u64);
336        let amt = (&mut write_slice[(pos as usize)..]).write(buf)?;
337        self.pos += amt as u64;
338        Ok(amt)
339    }
340
341    #[inline]
342    fn flush(&mut self) -> Result<()> { Ok(()) }
343}
344
345/// A generic trait describing an output stream.
346///
347/// See [`std::io::Write`] for more information.
348pub trait Write {
349    /// Writes `buf` into this writer, returning how many bytes were written.
350    ///
351    /// # Errors
352    ///
353    /// If an I/O error occurs while writing to the underlying writer.
354    fn write(&mut self, buf: &[u8]) -> Result<usize>;
355
356    /// Flushes this output stream, ensuring that all intermediately buffered contents
357    /// reach their destination.
358    ///
359    /// # Errors
360    ///
361    /// If an I/O error occurs while flushing the underlying writer.
362    fn flush(&mut self) -> Result<()>;
363
364    /// Attempts to write an entire buffer into this writer.
365    ///
366    /// # Errors
367    ///
368    /// If an I/O error occurs while writing to the underlying writer.
369    #[inline]
370    fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
371        while !buf.is_empty() {
372            match self.write(buf) {
373                Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
374                Ok(len) => buf = &buf[len..],
375                Err(e) if e.kind() == ErrorKind::Interrupted => {}
376                Err(e) => return Err(e),
377            }
378        }
379        Ok(())
380    }
381}
382
383impl<T: Write> Write for &'_ mut T {
384    #[inline]
385    fn write(&mut self, buf: &[u8]) -> Result<usize> { (**self).write(buf) }
386
387    #[inline]
388    fn write_all(&mut self, buf: &[u8]) -> Result<()> { (**self).write_all(buf) }
389
390    #[inline]
391    fn flush(&mut self) -> Result<()> { (**self).flush() }
392}
393
394#[cfg(feature = "alloc")]
395impl Write for alloc::vec::Vec<u8> {
396    #[inline]
397    fn write(&mut self, buf: &[u8]) -> Result<usize> {
398        self.extend_from_slice(buf);
399        Ok(buf.len())
400    }
401
402    #[inline]
403    fn flush(&mut self) -> Result<()> { Ok(()) }
404}
405
406impl Write for &mut [u8] {
407    #[inline]
408    fn write(&mut self, buf: &[u8]) -> Result<usize> {
409        let cnt = core::cmp::min(self.len(), buf.len());
410        self[..cnt].copy_from_slice(&buf[..cnt]);
411        *self = &mut core::mem::take(self)[cnt..];
412        Ok(cnt)
413    }
414
415    #[inline]
416    fn flush(&mut self) -> Result<()> { Ok(()) }
417}
418
419/// A sink to which all writes succeed.
420///
421/// Created using [`sink()`]. See [`std::io::Sink`] for more information.
422#[derive(Clone, Copy, Debug, Default)]
423pub struct Sink;
424
425impl Write for Sink {
426    #[inline]
427    fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
428
429    #[inline]
430    fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
431
432    #[inline]
433    fn flush(&mut self) -> Result<()> { Ok(()) }
434}
435
436/// Returns a sink to which all writes succeed.
437///
438/// See [`std::io::sink`] for more information.
439#[inline]
440pub fn sink() -> Sink { Sink }
441
442/// Wraps a `std` I/O type to implement the traits from this crate.
443///
444/// All methods are passed through converting the errors.
445#[cfg(feature = "std")]
446#[inline]
447pub const fn from_std<T>(std_io: T) -> FromStd<T> { FromStd::new(std_io) }
448
449/// Wraps a mutable reference to `std` I/O type to implement the traits from this crate.
450///
451/// All methods are passed through converting the errors.
452#[cfg(feature = "std")]
453#[inline]
454pub fn from_std_mut<T>(std_io: &mut T) -> &mut FromStd<T> { FromStd::new_mut(std_io) }
455
456/// Encodes a `consensus_encoding` object to an I/O writer.
457///
458/// # Errors
459///
460/// If an I/O error occurs while writing to the underlying writer.
461pub fn encode_to_writer<T, W>(object: &T, writer: W) -> Result<()>
462where
463    T: encoding::Encode + ?Sized,
464    W: Write,
465{
466    let mut encoder = object.encoder();
467    drain_to_writer(&mut encoder, writer)
468}
469
470/// Drains the output of an [`Encoder`] to an I/O writer.
471///
472/// See [`encode_to_writer`] for more information.
473///
474/// # Errors
475///
476/// Returns any I/O error encountered while writing to the writer.
477pub fn drain_to_writer<T, W>(encoder: &mut T, mut writer: W) -> Result<()>
478where
479    T: Encoder + ?Sized,
480    W: Write,
481{
482    loop {
483        writer.write_all(encoder.current_chunk())?;
484        if encoder.advance().has_finished() {
485            break;
486        }
487    }
488    Ok(())
489}
490
491/// Decodes an object from a buffered reader.
492///
493/// # Performance
494///
495/// For unbuffered readers (like [`std::fs::File`] or [`std::net::TcpStream`]), consider wrapping
496/// your reader with [`std::io::BufReader`] in order to use this function. This avoids frequent
497/// small reads, which can significantly impact performance.
498///
499/// # Errors
500///
501/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
502/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
503pub fn decode_from_read<T, R>(
504    reader: R,
505) -> core::result::Result<T, ReadError<<T::Decoder as Decoder>::Error>>
506where
507    T: Decode,
508    R: BufRead,
509{
510    decode_from_read_internal(reader, T::decoder())
511}
512
513/// Decodes an object from a buffered reader using a [`Decoder`] type.
514///
515/// Unlike [`decode_from_read`], this takes a generic [`Decoder`] parameter, allowing use with
516/// decoders which don't have a dedicated [`Decode`] implementer.
517///
518/// # Performance
519///
520/// For unbuffered readers (like [`std::fs::File`] or [`std::net::TcpStream`]), consider wrapping
521/// your reader with [`std::io::BufReader`] in order to use this function. This avoids frequent
522/// small reads, which can significantly impact performance.
523///
524/// # Errors
525///
526/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
527/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
528pub fn decode_from_read_with<D, R>(
529    reader: R,
530) -> core::result::Result<D::Output, ReadError<D::Error>>
531where
532    D: Decoder + Default,
533    R: BufRead,
534{
535    decode_from_read_internal(reader, D::default())
536}
537
538fn decode_from_read_internal<D, R>(
539    mut reader: R,
540    mut decoder: D,
541) -> core::result::Result<D::Output, ReadError<D::Error>>
542where
543    D: Decoder + Default,
544    R: BufRead,
545{
546    loop {
547        let mut buffer = match reader.fill_buf() {
548            Ok(buffer) => buffer,
549            // Auto retry read for non-fatal error.
550            Err(error) if error.kind() == ErrorKind::Interrupted => continue,
551            Err(error) => return Err(ReadError::Io(error)),
552        };
553
554        if buffer.is_empty() {
555            // EOF, but still try to finalize the decoder.
556            return decoder.end().map_err(ReadError::Decode);
557        }
558
559        let original_len = buffer.len();
560        let status = decoder.push_bytes(&mut buffer).map_err(ReadError::Decode)?;
561        let consumed = original_len - buffer.len();
562        reader.consume(consumed);
563
564        if status.is_ready() {
565            return decoder.end().map_err(ReadError::Decode);
566        }
567    }
568}
569
570/// Decodes an object from an unbuffered reader using a fixed-size buffer.
571///
572/// For most use cases, prefer [`decode_from_read`] with a [`std::io::BufReader`].
573/// This function is only needed when you have an unbuffered reader which you
574/// cannot wrap. It will probably have worse performance.
575///
576/// # Buffer
577///
578/// Uses a fixed 4KB (4096 bytes) stack-allocated buffer that is reused across
579/// read operations. This size is a good balance between memory usage and
580/// system call efficiency for most use cases.
581///
582/// For different buffer sizes, use [`decode_from_read_unbuffered_with`].
583///
584/// # Errors
585///
586/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
587/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
588pub fn decode_from_read_unbuffered<T, R>(
589    reader: R,
590) -> core::result::Result<T, ReadError<<T::Decoder as Decoder>::Error>>
591where
592    T: Decode,
593    R: Read,
594{
595    decode_from_read_unbuffered_with::<T, R, 4096>(reader)
596}
597
598/// Decodes an object from an unbuffered reader using a custom-sized buffer.
599///
600/// For most use cases, prefer [`decode_from_read`] with a [`std::io::BufReader`].
601/// This function is only needed when you have an unbuffered reader which you
602/// cannot wrap. It will probably have worse performance.
603///
604/// # Buffer
605///
606/// The `BUFFER_SIZE` parameter controls the intermediate buffer size used for
607/// reading. The buffer is allocated on the stack (not heap) and reused across
608/// read operations. Larger buffers reduce the number of system calls, but use
609/// more memory.
610///
611/// # Errors
612///
613/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
614/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
615pub fn decode_from_read_unbuffered_with<T, R, const BUFFER_SIZE: usize>(
616    mut reader: R,
617) -> core::result::Result<T, ReadError<<T::Decoder as Decoder>::Error>>
618where
619    T: Decode,
620    R: Read,
621{
622    let mut decoder = T::decoder();
623    let mut buffer = [0u8; BUFFER_SIZE];
624
625    while decoder.read_limit() > 0 {
626        // Only read what we need, up to buffer size.
627        let clamped_buffer = &mut buffer[..decoder.read_limit().min(BUFFER_SIZE)];
628        match reader.read(clamped_buffer) {
629            Ok(0) => {
630                // EOF, but still try to finalize the decoder.
631                return decoder.end().map_err(ReadError::Decode);
632            }
633            Ok(bytes_read) => {
634                let mut to_push = &clamped_buffer[..bytes_read];
635                while !to_push.is_empty() {
636                    if decoder.push_bytes(&mut to_push).map_err(ReadError::Decode)?.is_ready() {
637                        return decoder.end().map_err(ReadError::Decode);
638                    }
639                }
640            }
641            Err(ref e) if e.kind() == ErrorKind::Interrupted => {
642                // Auto retry read for non-fatal error.
643            }
644            Err(e) => return Err(ReadError::Io(e)),
645        }
646    }
647
648    decoder.end().map_err(ReadError::Decode)
649}
650
651#[cfg(feature = "std")]
652include!("../include/newtype.rs"); // Explained in `REPO_DIR/docs/README.md`.
653
654#[cfg(test)]
655mod tests {
656    #[cfg(feature = "alloc")]
657    #[cfg(not(feature = "std"))]
658    use alloc::{string::ToString, vec};
659    #[cfg(feature = "std")]
660    use std::{string::ToString, vec};
661
662    use encoding::{ArrayDecoder, ArrayEncoder, UnexpectedEofError};
663
664    use super::*;
665
666    #[test]
667    fn buf_read_fill_and_consume_slice() {
668        let data = [0_u8, 1, 2];
669
670        let mut slice = &data[..];
671
672        let fill = BufRead::fill_buf(&mut slice).unwrap();
673        assert_eq!(fill.len(), 3);
674        assert_eq!(fill, &[0_u8, 1, 2]);
675        slice.consume(2);
676
677        let fill = BufRead::fill_buf(&mut slice).unwrap();
678        assert_eq!(fill.len(), 1);
679        assert_eq!(fill, &[2_u8]);
680        slice.consume(1);
681
682        // checks we can attempt to read from a now-empty reader.
683        let fill = BufRead::fill_buf(&mut slice).unwrap();
684        assert!(fill.is_empty());
685    }
686
687    #[test]
688    #[cfg(feature = "alloc")]
689    fn read_to_limit_greater_than_total_length() {
690        let s = "16-byte-string!!".to_string();
691        let mut reader = Cursor::new(&s);
692        let mut buf = vec![];
693
694        // 32 is greater than the reader length.
695        let read = reader.read_to_limit(&mut buf, 32).expect("failed to read to limit");
696        assert_eq!(read, s.len());
697        assert_eq!(&buf, s.as_bytes());
698    }
699
700    #[test]
701    #[cfg(feature = "alloc")]
702    fn read_to_limit_less_than_total_length() {
703        let s = "16-byte-string!!".to_string();
704        let mut reader = Cursor::new(&s);
705        let mut buf = vec![];
706
707        let read = reader.read_to_limit(&mut buf, 2).expect("failed to read to limit");
708        assert_eq!(read, 2);
709        assert_eq!(&buf, "16".as_bytes());
710    }
711
712    #[test]
713    #[cfg(feature = "std")]
714    fn set_position_past_end_read_returns_eof() {
715        const BUF_LEN: usize = 64; // Just a small buffer.
716        let mut buf = [0_u8; BUF_LEN]; // We never actually write to this buffer.
717
718        let v = [1_u8; BUF_LEN];
719
720        // Sanity check the stdlib Cursor's behavior.
721        let mut c = std::io::Cursor::new(v);
722        for pos in [BUF_LEN, BUF_LEN + 1, BUF_LEN * 2] {
723            c.set_position(pos as u64);
724            let read = c.read(&mut buf).unwrap();
725            assert_eq!(read, 0);
726            assert_eq!(buf[0], 0x00); // Double check that buffer state is sane.
727        }
728
729        let mut c = Cursor::new(v);
730        for pos in [BUF_LEN, BUF_LEN + 1, BUF_LEN * 2] {
731            c.set_position(pos as u64);
732            let read = c.read(&mut buf).unwrap();
733            assert_eq!(read, 0);
734            assert_eq!(buf[0], 0x00); // Double check that buffer state is sane.
735        }
736    }
737
738    #[test]
739    fn read_into_zero_length_buffer() {
740        use crate::Read as _;
741
742        const BUF_LEN: usize = 64;
743        let data = [1_u8; BUF_LEN];
744        let mut buf = [0_u8; BUF_LEN];
745
746        let mut slice = data.as_ref();
747        let mut take = Read::take(&mut slice, 32);
748
749        let read = take.read(&mut buf[0..0]).unwrap();
750        assert_eq!(read, 0);
751        assert_eq!(buf[0], 0x00); // Check the buffer didn't get touched.
752    }
753
754    #[test]
755    #[cfg(feature = "alloc")]
756    fn take_and_read_to_end() {
757        const BUF_LEN: usize = 64;
758        let data = [1_u8; BUF_LEN];
759
760        let mut slice = data.as_ref();
761        let mut take = Read::take(&mut slice, 32);
762
763        let mut v = Vec::new();
764        let read = take.read_to_end(&mut v).unwrap();
765        assert_eq!(read, 32);
766        assert_eq!(data[0..32], v[0..32]);
767    }
768
769    #[test]
770    fn cursor_fill_buf_past_end() {
771        let data = [1, 2, 3];
772        let mut cursor = Cursor::new(&data);
773        cursor.set_position(10);
774
775        let buf = cursor.fill_buf().unwrap();
776        assert!(buf.is_empty());
777    }
778
779    #[test]
780    fn cursor_write() {
781        let data = [0x78, 0x56, 0x34, 0x12];
782
783        let mut buf = [0_u8; 4];
784        let mut cursor = Cursor::new(&mut buf);
785        let amt = cursor.write(&data).unwrap();
786
787        assert_eq!(buf, data);
788        assert_eq!(amt, 4);
789    }
790
791    #[test]
792    fn cursor_offset_write() {
793        let data = [0x78, 0x56, 0x34, 0x12];
794
795        let mut buf = [0_u8; 4];
796        let mut cursor = Cursor::new(&mut buf);
797        cursor.set_position(2);
798        let amt = cursor.write(&data).unwrap();
799
800        assert_eq!(buf, [0, 0, 0x78, 0x56]);
801        assert_eq!(amt, 2);
802    }
803
804    #[test]
805    fn cursor_consume_past_end() {
806        let data = [1, 2, 3];
807        let mut cursor = Cursor::new(&data);
808        cursor.set_position(10);
809
810        cursor.consume(5);
811        assert_eq!(cursor.position(), 15);
812    }
813
814    // Simple test type that implements Encode.
815    struct TestData(u32);
816
817    impl encoding::Encode for TestData {
818        type Encoder<'e>
819            = ArrayEncoder<4>
820        where
821            Self: 'e;
822
823        fn encoder(&self) -> Self::Encoder<'_> {
824            ArrayEncoder::without_length_prefix(self.0.to_le_bytes())
825        }
826    }
827
828    #[test]
829    fn encode_io_writer() {
830        let data = TestData(0x1234_5678);
831
832        let mut buf = [0_u8; 4];
833        encode_to_writer(&data, buf.as_mut_slice()).unwrap();
834
835        assert_eq!(buf, [0x78, 0x56, 0x34, 0x12]);
836    }
837
838    #[derive(Debug, PartialEq)]
839    struct TestArray([u8; 4]);
840
841    impl Decode for TestArray {
842        type Decoder = TestArrayDecoder;
843    }
844
845    #[derive(Default)]
846    struct TestArrayDecoder {
847        inner: ArrayDecoder<4>,
848    }
849
850    impl Decoder for TestArrayDecoder {
851        type Output = TestArray;
852        type Error = UnexpectedEofError;
853
854        fn push_bytes(
855            &mut self,
856            bytes: &mut &[u8],
857        ) -> core::result::Result<encoding::DecoderStatus, Self::Error> {
858            self.inner.push_bytes(bytes)
859        }
860
861        fn end(self) -> core::result::Result<Self::Output, Self::Error> {
862            self.inner.end().map(TestArray)
863        }
864
865        fn read_limit(&self) -> usize { self.inner.read_limit() }
866    }
867
868    #[test]
869    fn decode_from_read_success() {
870        let data = [1, 2, 3, 4];
871        let cursor = Cursor::new(&data);
872        let result: core::result::Result<TestArray, _> = decode_from_read(cursor);
873        assert!(result.is_ok());
874        let decoded = result.unwrap();
875        assert_eq!(decoded.0, [1, 2, 3, 4]);
876    }
877
878    #[test]
879    fn decode_from_read_unexpected_eof() {
880        let data = [1, 2, 3];
881        let cursor = Cursor::new(&data);
882        let result: core::result::Result<TestArray, _> = decode_from_read(cursor);
883        assert!(matches!(result, Err(ReadError::Decode(_))));
884    }
885
886    #[test]
887    fn decode_from_read_trait_object() {
888        let data = [1, 2, 3, 4];
889        let mut cursor = Cursor::new(&data);
890        // Test that we can pass a trait object (&mut dyn BufRead implements BufRead).
891        let reader: &mut dyn BufRead = &mut cursor;
892        let result: core::result::Result<TestArray, _> = decode_from_read(reader);
893        assert!(result.is_ok());
894        let decoded = result.unwrap();
895        assert_eq!(decoded.0, [1, 2, 3, 4]);
896    }
897
898    #[test]
899    #[cfg(feature = "alloc")]
900    fn decode_from_read_by_reference() {
901        use crate::alloc::vec::Vec;
902
903        let data = [1, 2, 3, 4];
904        let mut cursor = Cursor::new(&data);
905        // Test that we can pass by reference (&mut T implements BufRead when T: BufRead).
906        let result: core::result::Result<TestArray, _> = decode_from_read(&mut cursor);
907        assert!(result.is_ok());
908        let decoded = result.unwrap();
909        assert_eq!(decoded.0, [1, 2, 3, 4]);
910
911        let mut buf = Vec::new();
912        let _ = cursor.read_to_limit(&mut buf, 100);
913    }
914
915    #[test]
916    fn decode_from_read_unbuffered_success() {
917        let data = [1, 2, 3, 4];
918        let cursor = Cursor::new(&data);
919        let result: core::result::Result<TestArray, _> = decode_from_read_unbuffered(cursor);
920        assert!(result.is_ok());
921        let decoded = result.unwrap();
922        assert_eq!(decoded.0, [1, 2, 3, 4]);
923    }
924
925    #[test]
926    fn decode_from_read_unbuffered_unexpected_eof() {
927        let data = [1, 2, 3];
928        let cursor = Cursor::new(&data);
929        let result: core::result::Result<TestArray, _> = decode_from_read_unbuffered(cursor);
930        assert!(matches!(result, Err(ReadError::Decode(_))));
931    }
932
933    #[test]
934    fn decode_from_read_unbuffered_empty() {
935        let data = [];
936        let cursor = Cursor::new(&data);
937        let result: core::result::Result<TestArray, _> = decode_from_read_unbuffered(cursor);
938        assert!(matches!(result, Err(ReadError::Decode(_))));
939    }
940
941    #[test]
942    fn decode_from_read_unbuffered_extra_data() {
943        let data = [1, 2, 3, 4, 5, 6];
944        let cursor = Cursor::new(&data);
945        let result: core::result::Result<TestArray, _> = decode_from_read_unbuffered(cursor);
946        assert!(result.is_ok());
947        let decoded = result.unwrap();
948        assert_eq!(decoded.0, [1, 2, 3, 4]);
949    }
950
951    #[test]
952    #[cfg(feature = "alloc")]
953    fn decode_from_read_unbuffered_partial_consume() {
954        use encoding::DecoderStatus;
955
956        // Consumes one byte per push_bytes call. Returns Ready after
957        // it has accumulated 4 bytes. Checks for correct behaviour on
958        // partial consumption in push_bytes.
959        #[derive(Default)]
960        struct OneAtATimeDecoder {
961            buf: Vec<u8>,
962        }
963
964        #[derive(Debug, PartialEq)]
965        struct OneAtATime(Vec<u8>);
966
967        #[derive(Debug)]
968        struct OneAtATimeError;
969
970        impl Decoder for OneAtATimeDecoder {
971            type Output = OneAtATime;
972            type Error = OneAtATimeError;
973
974            fn push_bytes(
975                &mut self,
976                bytes: &mut &[u8],
977            ) -> core::result::Result<DecoderStatus, Self::Error> {
978                if self.buf.len() < 4 && !bytes.is_empty() {
979                    self.buf.push(bytes[0]);
980                    *bytes = &bytes[1..];
981                }
982                if self.buf.len() == 4 {
983                    Ok(DecoderStatus::Ready)
984                } else {
985                    Ok(DecoderStatus::NeedsMore)
986                }
987            }
988
989            fn end(self) -> core::result::Result<Self::Output, Self::Error> {
990                if self.buf.len() == 4 {
991                    Ok(OneAtATime(self.buf))
992                } else {
993                    Err(OneAtATimeError)
994                }
995            }
996
997            fn read_limit(&self) -> usize { 4 - self.buf.len() }
998        }
999
1000        impl Decode for OneAtATime {
1001            type Decoder = OneAtATimeDecoder;
1002        }
1003
1004        let data = [0x11, 0x22, 0x33, 0x44];
1005        let cursor = Cursor::new(&data);
1006        let decoded: OneAtATime =
1007            decode_from_read_unbuffered_with::<_, _, 16>(cursor).expect("decode succeeds");
1008        assert_eq!(decoded.0, vec![0x11, 0x22, 0x33, 0x44]);
1009    }
1010}