diff --git a/io/src/error.rs b/io/src/error.rs index 62fa7941..38d32619 100644 --- a/io/src/error.rs +++ b/io/src/error.rs @@ -2,6 +2,7 @@ use alloc::boxed::Box; use core::fmt::{Debug, Display, Formatter}; +/// The `io` crate error type. #[derive(Debug)] pub struct Error { kind: ErrorKind, @@ -13,6 +14,7 @@ pub struct Error { } impl Error { + /// Creates a new I/O error. #[cfg(feature = "std")] pub fn new(kind: ErrorKind, error: E) -> Error where @@ -21,18 +23,22 @@ impl Error { Self { kind, error: Some(error.into()) } } + /// Creates a new I/O error. #[cfg(all(feature = "alloc", not(feature = "std")))] pub fn new(kind: ErrorKind, error: E) -> Error { Self { kind, error: Some(error.into()) } } + /// Returns the error kind for this error. pub fn kind(&self) -> ErrorKind { self.kind } + /// Returns a reference to this error. #[cfg(feature = "std")] pub fn get_ref(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> { self.error.as_deref() } + /// Returns a reference to this error. #[cfg(all(feature = "alloc", not(feature = "std")))] pub fn get_ref(&self) -> Option<&(dyn Debug + Send + Sync + 'static)> { self.error.as_deref() } } @@ -97,15 +103,17 @@ impl From for std::io::Error { } macro_rules! define_errorkind { - ($($kind: ident),*) => { - #[non_exhaustive] + ($($(#[$($attr:tt)*])* $kind:ident),*) => { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] /// A minimal subset of [`std::io::ErrorKind`] which is used for [`Error`]. Note that, as with /// [`std::io`], only [`Self::Interrupted`] has defined semantics in this crate, all other /// variants are provided here only to provide higher-fidelity conversions to and from /// [`std::io::Error`]. pub enum ErrorKind { - $($kind),* + $( + $(#[$($attr)*])* + $kind + ),* } impl ErrorKind { @@ -134,24 +142,42 @@ macro_rules! define_errorkind { } define_errorkind!( + /// An entity was not found, often a file. NotFound, + /// The operation lacked the necessary privileges to complete. PermissionDenied, + /// The connection was refused by the remote server. ConnectionRefused, + /// The connection was reset by the remote server. ConnectionReset, + /// The connection was aborted (terminated) by the remote server. ConnectionAborted, + /// The network operation failed because it was not connected yet. NotConnected, + /// A socket address could not be bound because the address is already in use elsewhere. AddrInUse, + /// A nonexistent interface was requested or the requested address was not local. AddrNotAvailable, + /// The operation failed because a pipe was closed. BrokenPipe, + /// An entity already exists, often a file. AlreadyExists, + /// The operation needs to block to complete, but the blocking operation was requested to not occur. WouldBlock, + /// A parameter was incorrect. InvalidInput, + /// Data not valid for the operation were encountered. InvalidData, + /// The I/O operation’s timeout expired, causing it to be canceled. TimedOut, + /// An error returned when an operation could not be completed because a call to `write` returned `Ok(0)`. WriteZero, + /// This operation was interrupted. Interrupted, + /// An error returned when an operation could not be completed because an “end of file” was reached prematurely. UnexpectedEof, // Note: Any time we bump the MSRV any new error kinds should be added here! + /// A custom error that does not fall under any other I/O error kind Other ); diff --git a/io/src/lib.rs b/io/src/lib.rs index bde143e1..f397ba2f 100644 --- a/io/src/lib.rs +++ b/io/src/lib.rs @@ -14,7 +14,7 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] // Coding conventions. -// #![warn(missing_docs)] +#![warn(missing_docs)] // Exclude lints we don't think are valuable. #![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 @@ -34,12 +34,15 @@ use core::convert::TryInto; #[rustfmt::skip] // Keep public re-exports separate. pub use self::error::{Error, ErrorKind}; +/// Result type returned by functions in this crate. pub type Result = core::result::Result; /// A generic trait describing an input stream. See [`std::io::Read`] for more info. pub trait Read { + /// Reads bytes from source into `buf`. fn read(&mut self, buf: &mut [u8]) -> Result; + /// Reads bytes from source until `buf` is full. #[inline] fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> { while !buf.is_empty() { @@ -53,6 +56,7 @@ pub trait Read { Ok(()) } + /// Creates an adapter which will read at most `limit` bytes. #[inline] fn take(&mut self, limit: u64) -> Take { Take { reader: self, remaining: limit } } @@ -83,6 +87,9 @@ pub trait BufRead: Read { fn consume(&mut self, amount: usize); } +/// Reader adapter which limits the bytes read from an underlying reader. +/// +/// Created by calling `[Read::take]`. pub struct Take<'a, R: Read + ?Sized> { reader: &'a mut R, remaining: u64, @@ -182,18 +189,24 @@ impl BufRead for &[u8] { fn consume(&mut self, amount: usize) { *self = &self[amount..] } } +/// Wraps an in memory reader providing the `position` function. pub struct Cursor { inner: T, pos: u64, } impl> Cursor { + /// Creates a `Cursor` by wrapping `inner`. #[inline] pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } } + /// Returns the position read up to thus far. #[inline] pub fn position(&self) -> u64 { self.pos } + /// Returns the inner buffer. + /// + /// This is the whole wrapped buffer, including the bytes already read. #[inline] pub fn into_inner(self) -> T { self.inner } } @@ -227,10 +240,14 @@ impl> BufRead for Cursor { /// A generic trait describing an output stream. See [`std::io::Write`] for more info. pub trait Write { + /// Writes `buf` into this writer, returning how many bytes were written. fn write(&mut self, buf: &[u8]) -> Result; + /// Flushes this output stream, ensuring that all intermediately buffered contents + /// reach their destination. fn flush(&mut self) -> Result<()>; + /// Attempts to write an entire buffer into this writer. #[inline] fn write_all(&mut self, mut buf: &[u8]) -> Result<()> { while !buf.is_empty() { @@ -283,6 +300,8 @@ impl<'a> Write for &'a mut [u8] { } /// A sink to which all writes succeed. See [`std::io::Sink`] for more info. +/// +/// Created using `io::sink()`. pub struct Sink; #[cfg(not(feature = "std"))]