io: Add documentation to all public types and functions

Add docs for all public types and add a lint to enforce this going
forwards.

Use `allow` attribute in macro, will be fixed as a subsequent patch.
This commit is contained in:
Tobin C. Harding 2024-01-18 09:00:51 +11:00
parent 2810b08b0d
commit 83397c465c
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
2 changed files with 49 additions and 4 deletions

View File

@ -2,6 +2,7 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use core::fmt::{Debug, Display, Formatter}; use core::fmt::{Debug, Display, Formatter};
/// The `io` crate error type.
#[derive(Debug)] #[derive(Debug)]
pub struct Error { pub struct Error {
kind: ErrorKind, kind: ErrorKind,
@ -13,6 +14,7 @@ pub struct Error {
} }
impl Error { impl Error {
/// Creates a new I/O error.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn new<E>(kind: ErrorKind, error: E) -> Error pub fn new<E>(kind: ErrorKind, error: E) -> Error
where where
@ -21,18 +23,22 @@ impl Error {
Self { kind, error: Some(error.into()) } Self { kind, error: Some(error.into()) }
} }
/// Creates a new I/O error.
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub fn new<E: sealed::IntoBoxDynDebug>(kind: ErrorKind, error: E) -> Error { pub fn new<E: sealed::IntoBoxDynDebug>(kind: ErrorKind, error: E) -> Error {
Self { kind, error: Some(error.into()) } Self { kind, error: Some(error.into()) }
} }
/// Returns the error kind for this error.
pub fn kind(&self) -> ErrorKind { self.kind } pub fn kind(&self) -> ErrorKind { self.kind }
/// Returns a reference to this error.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn get_ref(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> { pub fn get_ref(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
self.error.as_deref() self.error.as_deref()
} }
/// Returns a reference to this error.
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub fn get_ref(&self) -> Option<&(dyn Debug + Send + Sync + 'static)> { self.error.as_deref() } pub fn get_ref(&self) -> Option<&(dyn Debug + Send + Sync + 'static)> { self.error.as_deref() }
} }
@ -97,15 +103,17 @@ impl From<Error> for std::io::Error {
} }
macro_rules! define_errorkind { macro_rules! define_errorkind {
($($kind: ident),*) => { ($($(#[$($attr:tt)*])* $kind:ident),*) => {
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
/// A minimal subset of [`std::io::ErrorKind`] which is used for [`Error`]. Note that, as with /// 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 /// [`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 /// variants are provided here only to provide higher-fidelity conversions to and from
/// [`std::io::Error`]. /// [`std::io::Error`].
pub enum ErrorKind { pub enum ErrorKind {
$($kind),* $(
$(#[$($attr)*])*
$kind
),*
} }
impl ErrorKind { impl ErrorKind {
@ -134,24 +142,42 @@ macro_rules! define_errorkind {
} }
define_errorkind!( define_errorkind!(
/// An entity was not found, often a file.
NotFound, NotFound,
/// The operation lacked the necessary privileges to complete.
PermissionDenied, PermissionDenied,
/// The connection was refused by the remote server.
ConnectionRefused, ConnectionRefused,
/// The connection was reset by the remote server.
ConnectionReset, ConnectionReset,
/// The connection was aborted (terminated) by the remote server.
ConnectionAborted, ConnectionAborted,
/// The network operation failed because it was not connected yet.
NotConnected, NotConnected,
/// A socket address could not be bound because the address is already in use elsewhere.
AddrInUse, AddrInUse,
/// A nonexistent interface was requested or the requested address was not local.
AddrNotAvailable, AddrNotAvailable,
/// The operation failed because a pipe was closed.
BrokenPipe, BrokenPipe,
/// An entity already exists, often a file.
AlreadyExists, AlreadyExists,
/// The operation needs to block to complete, but the blocking operation was requested to not occur.
WouldBlock, WouldBlock,
/// A parameter was incorrect.
InvalidInput, InvalidInput,
/// Data not valid for the operation were encountered.
InvalidData, InvalidData,
/// The I/O operations timeout expired, causing it to be canceled.
TimedOut, TimedOut,
/// An error returned when an operation could not be completed because a call to `write` returned `Ok(0)`.
WriteZero, WriteZero,
/// This operation was interrupted.
Interrupted, Interrupted,
/// An error returned when an operation could not be completed because an “end of file” was reached prematurely.
UnexpectedEof, UnexpectedEof,
// Note: Any time we bump the MSRV any new error kinds should be added here! // 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 Other
); );

View File

@ -14,7 +14,7 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
// Coding conventions. // Coding conventions.
// #![warn(missing_docs)] #![warn(missing_docs)]
// Exclude lints we don't think are valuable. // Exclude lints we don't think are valuable.
#![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 #![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. #[rustfmt::skip] // Keep public re-exports separate.
pub use self::error::{Error, ErrorKind}; pub use self::error::{Error, ErrorKind};
/// Result type returned by functions in this crate.
pub type Result<T> = core::result::Result<T, Error>; pub type Result<T> = core::result::Result<T, Error>;
/// A generic trait describing an input stream. See [`std::io::Read`] for more info. /// A generic trait describing an input stream. See [`std::io::Read`] for more info.
pub trait Read { pub trait Read {
/// Reads bytes from source into `buf`.
fn read(&mut self, buf: &mut [u8]) -> Result<usize>; fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
/// Reads bytes from source until `buf` is full.
#[inline] #[inline]
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> { fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() { while !buf.is_empty() {
@ -53,6 +56,7 @@ pub trait Read {
Ok(()) Ok(())
} }
/// Creates an adapter which will read at most `limit` bytes.
#[inline] #[inline]
fn take(&mut self, limit: u64) -> Take<Self> { Take { reader: self, remaining: limit } } fn take(&mut self, limit: u64) -> Take<Self> { Take { reader: self, remaining: limit } }
@ -83,6 +87,9 @@ pub trait BufRead: Read {
fn consume(&mut self, amount: usize); 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> { pub struct Take<'a, R: Read + ?Sized> {
reader: &'a mut R, reader: &'a mut R,
remaining: u64, remaining: u64,
@ -182,18 +189,24 @@ impl BufRead for &[u8] {
fn consume(&mut self, amount: usize) { *self = &self[amount..] } fn consume(&mut self, amount: usize) { *self = &self[amount..] }
} }
/// Wraps an in memory reader providing the `position` function.
pub struct Cursor<T> { pub struct Cursor<T> {
inner: T, inner: T,
pos: u64, pos: u64,
} }
impl<T: AsRef<[u8]>> Cursor<T> { impl<T: AsRef<[u8]>> Cursor<T> {
/// Creates a `Cursor` by wrapping `inner`.
#[inline] #[inline]
pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } } pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } }
/// Returns the position read up to thus far.
#[inline] #[inline]
pub fn position(&self) -> u64 { self.pos } pub fn position(&self) -> u64 { self.pos }
/// Returns the inner buffer.
///
/// This is the whole wrapped buffer, including the bytes already read.
#[inline] #[inline]
pub fn into_inner(self) -> T { self.inner } pub fn into_inner(self) -> T { self.inner }
} }
@ -227,10 +240,14 @@ impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
/// A generic trait describing an output stream. See [`std::io::Write`] for more info. /// A generic trait describing an output stream. See [`std::io::Write`] for more info.
pub trait Write { pub trait Write {
/// Writes `buf` into this writer, returning how many bytes were written.
fn write(&mut self, buf: &[u8]) -> Result<usize>; fn write(&mut self, buf: &[u8]) -> Result<usize>;
/// Flushes this output stream, ensuring that all intermediately buffered contents
/// reach their destination.
fn flush(&mut self) -> Result<()>; fn flush(&mut self) -> Result<()>;
/// Attempts to write an entire buffer into this writer.
#[inline] #[inline]
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> { fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() { 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. /// A sink to which all writes succeed. See [`std::io::Sink`] for more info.
///
/// Created using `io::sink()`.
pub struct Sink; pub struct Sink;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]