rust-bitcoin-unsafe-fast/io/tests/api.rs

141 lines
3.5 KiB
Rust

//! 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: <https://rust-lang.github.io/api-guidelines/about.html>
#![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<u32>,
#[cfg(feature = "std")]
b: ToStd<Dummy>,
c: Cursor<Dummy>,
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<usize, io::Error> {
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<usize, io::Error> { 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<T: Send>() {}
assert_send::<Types>();
fn assert_sync<T: Sync>() {}
assert_sync::<Types>();
}