diff --git a/api/io/all-features.txt b/api/io/all-features.txt index 055e6305d..fe3da3040 100644 --- a/api/io/all-features.txt +++ b/api/io/all-features.txt @@ -56,6 +56,7 @@ impl core::convert::From for bitcoin_io::Error impl core::error::Error for bitcoin_io::Error impl core::fmt::Debug for bitcoin_io::Error impl core::fmt::Debug for bitcoin_io::ErrorKind +impl core::fmt::Debug for bitcoin_io::Sink impl core::fmt::Display for bitcoin_io::Error impl core::hash::Hash for bitcoin_io::ErrorKind impl core::marker::Copy for bitcoin_io::ErrorKind @@ -76,6 +77,7 @@ impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Sink impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::ErrorKind impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::Sink impl std::io::Write for bitcoin_io::Sink +impl<'a, R: core::fmt::Debug + bitcoin_io::Read + ?core::marker::Sized> core::fmt::Debug for bitcoin_io::Take<'a, R> impl<'a, R> !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Take<'a, R> impl<'a, R> core::marker::Freeze for bitcoin_io::Take<'a, R> where R: ?core::marker::Sized impl<'a, R> core::marker::Send for bitcoin_io::Take<'a, R> where R: core::marker::Send + ?core::marker::Sized @@ -105,6 +107,9 @@ impl> bitcoin_io::BufRead for std::io::cursor::Cur impl> bitcoin_io::Cursor impl> bitcoin_io::Read for bitcoin_io::Cursor impl> bitcoin_io::Read for std::io::cursor::Cursor +impl core::fmt::Debug for bitcoin_io::Cursor +impl core::fmt::Debug for bitcoin_io::FromStd +impl core::fmt::Debug for bitcoin_io::ToStd impl bitcoin_io::BufRead for bitcoin_io::FromStd impl std::io::BufRead for bitcoin_io::FromStd impl bitcoin_io::Read for bitcoin_io::FromStd @@ -214,6 +219,7 @@ pub fn bitcoin_io::BufRead::consume(&mut self, amount: usize) pub fn bitcoin_io::BufRead::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Cursor::consume(&mut self, amount: usize) pub fn bitcoin_io::Cursor::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> +pub fn bitcoin_io::Cursor::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Cursor::get_mut(&mut self) -> &mut T pub fn bitcoin_io::Cursor::get_ref(&self) -> &T pub fn bitcoin_io::Cursor::inner(&self) -> &T @@ -242,6 +248,7 @@ pub fn bitcoin_io::FromStd::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::FromStd::fill_buf(&mut self) -> std::io::error::Result<&[u8]> pub fn bitcoin_io::FromStd::flush(&mut self) -> bitcoin_io::Result<()> pub fn bitcoin_io::FromStd::flush(&mut self) -> std::io::error::Result<()> +pub fn bitcoin_io::FromStd::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::FromStd::get_mut(&mut self) -> &mut T pub fn bitcoin_io::FromStd::get_ref(&self) -> &T pub fn bitcoin_io::FromStd::inner(&self) -> &T @@ -263,6 +270,7 @@ pub fn bitcoin_io::Read::read_to_limit(&mut self, buf: &mut alloc::vec::Vec, pub fn bitcoin_io::Read::take(&mut self, limit: u64) -> bitcoin_io::Take<'_, Self> pub fn bitcoin_io::Sink::flush(&mut self) -> bitcoin_io::Result<()> pub fn bitcoin_io::Sink::flush(&mut self) -> std::io::error::Result<()> +pub fn bitcoin_io::Sink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Sink::write(&mut self, buf: &[u8]) -> bitcoin_io::Result pub fn bitcoin_io::Sink::write(&mut self, buf: &[u8]) -> std::io::error::Result pub fn bitcoin_io::Sink::write_all(&mut self, _: &[u8]) -> bitcoin_io::Result<()> @@ -271,11 +279,13 @@ pub fn bitcoin_io::Take<'_, R>::consume(&mut self, amount: usize) pub fn bitcoin_io::Take<'_, R>::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Take<'_, R>::read(&mut self, buf: &mut [u8]) -> bitcoin_io::Result pub fn bitcoin_io::Take<'_, R>::read_to_end(&mut self, buf: &mut alloc::vec::Vec) -> bitcoin_io::Result +pub fn bitcoin_io::Take<'a, R>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::ToStd::consume(&mut self, amount: usize) pub fn bitcoin_io::ToStd::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::ToStd::fill_buf(&mut self) -> std::io::error::Result<&[u8]> pub fn bitcoin_io::ToStd::flush(&mut self) -> bitcoin_io::Result<()> pub fn bitcoin_io::ToStd::flush(&mut self) -> std::io::error::Result<()> +pub fn bitcoin_io::ToStd::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::ToStd::inner(&self) -> &T pub fn bitcoin_io::ToStd::inner_mut(&mut self) -> &mut T pub fn bitcoin_io::ToStd::into_inner(self) -> T diff --git a/api/io/alloc-only.txt b/api/io/alloc-only.txt index 572cb17e1..751069688 100644 --- a/api/io/alloc-only.txt +++ b/api/io/alloc-only.txt @@ -14,6 +14,7 @@ impl core::convert::From for bitcoin_io::Error impl core::convert::From for bitcoin_io::ErrorKind impl core::fmt::Debug for bitcoin_io::Error impl core::fmt::Debug for bitcoin_io::ErrorKind +impl core::fmt::Debug for bitcoin_io::Sink impl core::fmt::Display for bitcoin_io::Error impl core::hash::Hash for bitcoin_io::ErrorKind impl core::marker::Copy for bitcoin_io::ErrorKind @@ -33,6 +34,7 @@ impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::ErrorKind impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Sink impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::ErrorKind impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::Sink +impl<'a, R: core::fmt::Debug + bitcoin_io::Read + ?core::marker::Sized> core::fmt::Debug for bitcoin_io::Take<'a, R> impl<'a, R> !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Take<'a, R> impl<'a, R> core::marker::Freeze for bitcoin_io::Take<'a, R> where R: ?core::marker::Sized impl<'a, R> core::marker::Send for bitcoin_io::Take<'a, R> where R: core::marker::Send + ?core::marker::Sized @@ -48,6 +50,7 @@ impl bitcoin_io::Write for &mut T impl> bitcoin_io::BufRead for bitcoin_io::Cursor impl> bitcoin_io::Cursor impl> bitcoin_io::Read for bitcoin_io::Cursor +impl core::fmt::Debug for bitcoin_io::Cursor impl core::marker::Freeze for bitcoin_io::Cursor where T: core::marker::Freeze impl core::marker::Send for bitcoin_io::Cursor where T: core::marker::Send impl core::marker::Sync for bitcoin_io::Cursor where T: core::marker::Sync @@ -91,6 +94,7 @@ pub fn bitcoin_io::BufRead::consume(&mut self, amount: usize) pub fn bitcoin_io::BufRead::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Cursor::consume(&mut self, amount: usize) pub fn bitcoin_io::Cursor::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> +pub fn bitcoin_io::Cursor::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Cursor::get_mut(&mut self) -> &mut T pub fn bitcoin_io::Cursor::get_ref(&self) -> &T pub fn bitcoin_io::Cursor::inner(&self) -> &T @@ -115,12 +119,14 @@ pub fn bitcoin_io::Read::read_exact(&mut self, buf: &mut [u8]) -> bitcoin_io::Re pub fn bitcoin_io::Read::read_to_limit(&mut self, buf: &mut alloc::vec::Vec, limit: u64) -> bitcoin_io::Result pub fn bitcoin_io::Read::take(&mut self, limit: u64) -> bitcoin_io::Take<'_, Self> pub fn bitcoin_io::Sink::flush(&mut self) -> bitcoin_io::Result<()> +pub fn bitcoin_io::Sink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Sink::write(&mut self, buf: &[u8]) -> bitcoin_io::Result pub fn bitcoin_io::Sink::write_all(&mut self, _: &[u8]) -> bitcoin_io::Result<()> pub fn bitcoin_io::Take<'_, R>::consume(&mut self, amount: usize) pub fn bitcoin_io::Take<'_, R>::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Take<'_, R>::read(&mut self, buf: &mut [u8]) -> bitcoin_io::Result pub fn bitcoin_io::Take<'_, R>::read_to_end(&mut self, buf: &mut alloc::vec::Vec) -> bitcoin_io::Result +pub fn bitcoin_io::Take<'a, R>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Write::flush(&mut self) -> bitcoin_io::Result<()> pub fn bitcoin_io::Write::write(&mut self, buf: &[u8]) -> bitcoin_io::Result pub fn bitcoin_io::Write::write_all(&mut self, buf: &[u8]) -> bitcoin_io::Result<()> diff --git a/api/io/no-features.txt b/api/io/no-features.txt index 93613d4e6..0874dbcd9 100644 --- a/api/io/no-features.txt +++ b/api/io/no-features.txt @@ -13,6 +13,7 @@ impl core::convert::From for bitcoin_io::Error impl core::convert::From for bitcoin_io::ErrorKind impl core::fmt::Debug for bitcoin_io::Error impl core::fmt::Debug for bitcoin_io::ErrorKind +impl core::fmt::Debug for bitcoin_io::Sink impl core::fmt::Display for bitcoin_io::Error impl core::hash::Hash for bitcoin_io::ErrorKind impl core::marker::Copy for bitcoin_io::ErrorKind @@ -32,6 +33,7 @@ impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::ErrorKind impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Sink impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::ErrorKind impl core::panic::unwind_safe::UnwindSafe for bitcoin_io::Sink +impl<'a, R: core::fmt::Debug + bitcoin_io::Read + ?core::marker::Sized> core::fmt::Debug for bitcoin_io::Take<'a, R> impl<'a, R> !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Take<'a, R> impl<'a, R> core::marker::Freeze for bitcoin_io::Take<'a, R> where R: ?core::marker::Sized impl<'a, R> core::marker::Send for bitcoin_io::Take<'a, R> where R: core::marker::Send + ?core::marker::Sized @@ -46,6 +48,7 @@ impl bitcoin_io::Write for &mut T impl> bitcoin_io::BufRead for bitcoin_io::Cursor impl> bitcoin_io::Cursor impl> bitcoin_io::Read for bitcoin_io::Cursor +impl core::fmt::Debug for bitcoin_io::Cursor impl core::marker::Freeze for bitcoin_io::Cursor where T: core::marker::Freeze impl core::marker::Send for bitcoin_io::Cursor where T: core::marker::Send impl core::marker::Sync for bitcoin_io::Cursor where T: core::marker::Sync @@ -87,6 +90,7 @@ pub fn bitcoin_io::BufRead::consume(&mut self, amount: usize) pub fn bitcoin_io::BufRead::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Cursor::consume(&mut self, amount: usize) pub fn bitcoin_io::Cursor::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> +pub fn bitcoin_io::Cursor::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Cursor::get_mut(&mut self) -> &mut T pub fn bitcoin_io::Cursor::get_ref(&self) -> &T pub fn bitcoin_io::Cursor::inner(&self) -> &T @@ -108,11 +112,13 @@ pub fn bitcoin_io::Read::read(&mut self, buf: &mut [u8]) -> bitcoin_io::Result bitcoin_io::Result<()> pub fn bitcoin_io::Read::take(&mut self, limit: u64) -> bitcoin_io::Take<'_, Self> pub fn bitcoin_io::Sink::flush(&mut self) -> bitcoin_io::Result<()> +pub fn bitcoin_io::Sink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Sink::write(&mut self, buf: &[u8]) -> bitcoin_io::Result pub fn bitcoin_io::Sink::write_all(&mut self, _: &[u8]) -> bitcoin_io::Result<()> pub fn bitcoin_io::Take<'_, R>::consume(&mut self, amount: usize) pub fn bitcoin_io::Take<'_, R>::fill_buf(&mut self) -> bitcoin_io::Result<&[u8]> pub fn bitcoin_io::Take<'_, R>::read(&mut self, buf: &mut [u8]) -> bitcoin_io::Result +pub fn bitcoin_io::Take<'a, R>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bitcoin_io::Write::flush(&mut self) -> bitcoin_io::Result<()> pub fn bitcoin_io::Write::write(&mut self, buf: &[u8]) -> bitcoin_io::Result pub fn bitcoin_io::Write::write_all(&mut self, buf: &[u8]) -> bitcoin_io::Result<()> diff --git a/io/src/bridge.rs b/io/src/bridge.rs index a979f7387..471a6aba0 100644 --- a/io/src/bridge.rs +++ b/io/src/bridge.rs @@ -5,6 +5,7 @@ use internals::rust_version; /// A bridging wrapper providing the IO traits for types that already implement `std` IO traits. #[repr(transparent)] +#[derive(Debug)] pub struct FromStd(T); impl FromStd { @@ -116,6 +117,7 @@ impl std::io::Write for FromStd { /// A bridging wrapper providing the std traits for types that already implement our traits. #[repr(transparent)] +#[derive(Debug)] pub struct ToStd(T); impl ToStd { @@ -123,18 +125,6 @@ impl ToStd { #[inline] pub const fn new(inner: T) -> Self { Self(inner) } - /// Returns the wrapped value. - #[inline] - pub fn into_inner(self) -> T { self.0 } - - /// Returns a reference to the wrapped value. - #[inline] - pub fn inner(&self) -> &T { &self.0 } - - /// Returns a mutable reference to the wrapped value. - #[inline] - pub fn inner_mut(&mut self) -> &mut T { &mut self.0 } - /// Wraps a mutable reference to IO type. #[inline] pub fn new_mut(inner: &mut T) -> &mut Self { @@ -149,6 +139,18 @@ impl ToStd { // SAFETY: the type is repr(transparent) and the pointer is created from Box unsafe { Box::from_raw(Box::into_raw(inner) as *mut Self) } } + + /// Returns the wrapped value. + #[inline] + pub fn into_inner(self) -> T { self.0 } + + /// Returns a reference to the wrapped value. + #[inline] + pub fn inner(&self) -> &T { &self.0 } + + /// Returns a mutable reference to the wrapped value. + #[inline] + pub fn inner_mut(&mut self) -> &mut T { &mut self.0 } } impl std::io::Read for ToStd { diff --git a/io/src/lib.rs b/io/src/lib.rs index 35e12b631..c8d846dd5 100644 --- a/io/src/lib.rs +++ b/io/src/lib.rs @@ -94,6 +94,7 @@ pub trait BufRead: Read { /// Reader adapter which limits the bytes read from an underlying reader. /// /// Created by calling `[Read::take]`. +#[derive(Debug)] pub struct Take<'a, R: Read + ?Sized> { reader: &'a mut R, remaining: u64, @@ -191,6 +192,7 @@ impl BufRead for &[u8] { } /// Wraps an in memory reader providing the `position` function. +#[derive(Debug)] pub struct Cursor { inner: T, pos: u64, @@ -329,6 +331,7 @@ impl Write for &mut [u8] { /// A sink to which all writes succeed. See [`std::io::Sink`] for more info. /// /// Created using `io::sink()`. +#[derive(Debug)] pub struct Sink; impl Write for Sink { diff --git a/io/tests/api.rs b/io/tests/api.rs new file mode 100644 index 000000000..426f427ad --- /dev/null +++ b/io/tests/api.rs @@ -0,0 +1,140 @@ +//! Test the API surface of `io`. +//! +//! The point of these tests are to check the API surface as opposed to test the API functionality. +//! +//! ref: + +#![allow(dead_code)] +#![allow(unused_imports)] + +use core::cell::Cell; +use core::convert::Infallible; + +// These imports test "typical" usage by user code. +use bitcoin_io::{self as io, BufRead, Cursor, ErrorKind, Read, Sink, Take, Write}; +#[cfg(feature = "std")] +use bitcoin_io::{FromStd, ToStd}; + +/// An arbitrary error kind. +const ERROR_KIND: ErrorKind = ErrorKind::TimedOut; + +/// A struct that includes all public non-error enums. +#[derive(Debug)] // All public types implement Debug (C-DEBUG). +struct Enums { + a: ErrorKind, +} + +impl Enums { + /// Creates an arbitrary `Enums` instance. + fn new() -> Self { Self { a: ERROR_KIND } } +} + +/// A struct that includes all public non-error structs except `Take`. +#[derive(Debug)] // All public types implement Debug (C-DEBUG). +struct Structs { + #[cfg(feature = "std")] + a: FromStd, + #[cfg(feature = "std")] + b: ToStd, + c: Cursor, + d: Sink, +} + +impl Structs { + fn new() -> Self { + Self { + #[cfg(feature = "std")] + a: FromStd::new(0), + #[cfg(feature = "std")] + b: ToStd::new(DUMMY), + c: Cursor::new(DUMMY), + d: Sink, + } + } +} + +#[derive(Debug)] // `Take` implements Debug (C-DEBUG). +struct Taker<'a> { + a: Take<'a, Dummy>, +} + +/// An arbitrary `Dummy` instance. +static DUMMY: Dummy = Dummy(0); + +/// Dummy struct to implement all the traits we provide. +#[derive(Debug, Copy, Clone)] +struct Dummy(u64); + +impl Read for Dummy { + fn read(&mut self, buf: &mut [u8]) -> Result { + if buf.is_empty() { + Ok(0) + } else { + buf[0] = (self.0 & 0xFF) as u8; + Ok(1) + } + } +} + +impl BufRead for Dummy { + fn fill_buf(&mut self) -> Result<&[u8], io::Error> { Ok(&[]) } + fn consume(&mut self, _: usize) {} +} + +impl Write for Dummy { + fn write(&mut self, buf: &[u8]) -> Result { Ok(buf.len()) } + fn write_all(&mut self, _: &[u8]) -> Result<(), io::Error> { Ok(()) } + fn flush(&mut self) -> Result<(), io::Error> { Ok(()) } +} + +impl AsRef<[u8]> for Dummy { + fn as_ref(&self) -> &[u8] { &[] } +} + +/// A struct that includes all public non-error types. +#[derive(Debug)] // All public types implement Debug (C-DEBUG). +struct Types { + a: Enums, + b: Structs, +} + +impl Types { + fn new() -> Self { Self { a: Enums::new(), b: Structs::new() } } +} + +/// A struct that includes all public error types. +#[derive(Debug)] // `io::Error` only implements `Debug`. +struct Errors { + a: io::Error, +} + +// `Debug` representation is never empty (C-DEBUG-NONEMPTY). +#[test] +fn api_all_non_error_types_have_non_empty_debug() { + let t = Types::new(); + + let debug = format!("{:?}", t.a.a); + assert!(!debug.is_empty()); + + #[cfg(feature = "std")] + { + let debug = format!("{:?}", t.b.a); + assert!(!debug.is_empty()); + let debug = format!("{:?}", t.b.b); + assert!(!debug.is_empty()); + } + let debug = format!("{:?}", t.b.c); + assert!(!debug.is_empty()); + let debug = format!("{:?}", t.b.d); + assert!(!debug.is_empty()); +} + +// Types are `Send` and `Sync` where possible (C-SEND-SYNC). +#[test] +fn all_non_error_tyes_implement_send_sync() { + fn assert_send() {} + assert_send::(); + + fn assert_sync() {} + assert_sync::(); +} diff --git a/units/tests/api.rs b/units/tests/api.rs index 647e29903..63bdd7fe0 100644 --- a/units/tests/api.rs +++ b/units/tests/api.rs @@ -4,26 +4,14 @@ //! //! The point of these tests are to check the API surface as opposed to test the API functionality. //! -//! What this module tests: -//! -//! - The location of re-exports for various typical usage styles. -//! - Regressions in the API surface (things being accidentally moved). -//! - All public types implement Debug (C-DEBUG). -//! - For all non-error types: -//! - `Debug` representation is never empty (C-DEBUG-NONEMPTY) -//! - For all error types: -//! - Derive standard traits as defined by `rust-bitcoin` policy. -//! -//! This file was created by referring to the output of `cargo check-api`. -//! //! ref: #![allow(dead_code)] #![allow(unused_imports)] -// These imports test "typical" usage by user code. #[cfg(feature = "arbitrary")] use arbitrary::{Arbitrary, Unstructured}; +// These imports test "typical" usage by user code. use bitcoin_units::locktime::{absolute, relative}; // Typical usage is `absolute::Height`. use bitcoin_units::{ amount, block, fee_rate, locktime, parse, weight, Amount, BlockHeight, BlockInterval, FeeRate,