Merge rust-bitcoin/rust-bitcoin#2234: Inline io module in the io crate root

f764a607ac Use conventional import path for io crate (Tobin C. Harding)
5c0759a390 Inline io module in io crate root (Tobin C. Harding)
80fe9b99b2 Move public macros to a separate module (Tobin C. Harding)

Pull request description:

  Its not immediately obvious why we nest the whole `io` code in an `io` submodule within `lib.rs`. As far as I can tell we can inline it and re-export from `rust-bitcoin` same as we do for our other dependencies.

  This change would effect other users of the crate but since the `io` crate is unreleased this effects no-one except us.

  After doing this it might be because `crate::io::Foo` looks good when near `std::io::Foo`?

ACKs for top commit:
  apoelstra:
    ACK f764a607ac
  Kixunil:
    ACK f764a607ac

Tree-SHA512: 38888b0c23d5f2cd874f77dd332fe4fa4b9acb90e3a2dac19e62ed3d98151acd7480c719aa85434e1a3de987af2c4f565528a914a14d5fd3f0f0e410cbdf5d40
This commit is contained in:
Andrew Poelstra 2023-11-30 17:46:14 +00:00
commit a3f6f53d37
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
23 changed files with 386 additions and 394 deletions

View File

@ -27,8 +27,8 @@ bitcoinconsensus-std = ["bitcoinconsensus/std", "std"]
# The no-std feature doesn't disable std - you need to turn off the std feature for that by disabling default. # The no-std feature doesn't disable std - you need to turn off the std feature for that by disabling default.
# Instead no-std enables additional features required for this crate to be usable without std. # Instead no-std enables additional features required for this crate to be usable without std.
# As a result, both can be enabled without conflict. # As a result, both can be enabled without conflict.
std = ["secp256k1/std", "bitcoin-io/std", "hashes/std", "bech32/std", "internals/std", "hex/std"] std = ["secp256k1/std", "io/std", "hashes/std", "bech32/std", "internals/std", "hex/std"]
no-std = ["hashes/alloc", "hashes/io", "bitcoin-io/alloc", "bech32/alloc", "secp256k1/alloc", "hex/alloc"] no-std = ["hashes/alloc", "hashes/io", "io/alloc", "bech32/alloc", "secp256k1/alloc", "hex/alloc"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
@ -40,10 +40,9 @@ hex = { package = "hex-conservative", version = "0.1.1", default-features = fals
bech32 = { version = "0.10.0-beta", default-features = false } bech32 = { version = "0.10.0-beta", default-features = false }
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false } hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false }
secp256k1 = { version = "0.28.0", default-features = false, features = ["hashes"] } secp256k1 = { version = "0.28.0", default-features = false, features = ["hashes"] }
io = { package = "bitcoin-io", version = "0.1", default-features = false }
hex_lit = "0.1.1" hex_lit = "0.1.1"
bitcoin-io = { version = "0.1", default-features = false }
base64 = { version = "0.21.3", optional = true } base64 = { version = "0.21.3", optional = true }
# Only use this feature for no-std builds, otherwise use bitcoinconsensus-std. # Only use this feature for no-std builds, otherwise use bitcoinconsensus-std.
bitcoinconsensus = { version = "0.20.2-0.5.0", default-features = false, optional = true } bitcoinconsensus = { version = "0.20.2-0.5.0", default-features = false, optional = true }

View File

@ -12,7 +12,6 @@ use core::str::FromStr;
use core::{default, ops}; use core::{default, ops};
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
use crate::io;
use crate::prelude::*; use crate::prelude::*;
/// A set of denominations in which amounts can be expressed. /// A set of denominations in which amounts can be expressed.

View File

@ -50,7 +50,6 @@ use crate::blockdata::transaction::OutPoint;
use crate::consensus::encode::VarInt; use crate::consensus::encode::VarInt;
use crate::consensus::{Decodable, Encodable}; use crate::consensus::{Decodable, Encodable};
use crate::hash_types::{BlockHash, FilterHash, FilterHeader}; use crate::hash_types::{BlockHash, FilterHash, FilterHeader};
use crate::io;
use crate::prelude::*; use crate::prelude::*;
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845 /// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845

View File

@ -13,6 +13,7 @@ use core::{fmt, slice};
use hashes::{hash160, hash_newtype, sha512, Hash, HashEngine, Hmac, HmacEngine}; use hashes::{hash160, hash_newtype, sha512, Hash, HashEngine, Hmac, HmacEngine};
use internals::{impl_array_newtype, write_err}; use internals::{impl_array_newtype, write_err};
use io::Write;
use secp256k1::{self, Secp256k1, XOnlyPublicKey}; use secp256k1::{self, Secp256k1, XOnlyPublicKey};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde; use serde;
@ -20,7 +21,6 @@ use serde;
use crate::base58; use crate::base58;
use crate::crypto::key::{self, Keypair, PrivateKey, PublicKey}; use crate::crypto::key::{self, Keypair, PrivateKey, PublicKey};
use crate::internal_macros::impl_bytes_newtype; use crate::internal_macros::impl_bytes_newtype;
use crate::io::Write;
use crate::network::Network; use crate::network::Network;
use crate::prelude::*; use crate::prelude::*;

View File

@ -20,7 +20,7 @@ use crate::hash_types::{TxMerkleNode, WitnessCommitment, WitnessMerkleNode, Wtxi
use crate::internal_macros::impl_consensus_encoding; use crate::internal_macros::impl_consensus_encoding;
use crate::pow::{CompactTarget, Target, Work}; use crate::pow::{CompactTarget, Target, Work};
use crate::prelude::*; use crate::prelude::*;
use crate::{io, merkle_tree, Network, VarInt}; use crate::{merkle_tree, Network, VarInt};
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)] #[doc(inline)]
@ -645,9 +645,10 @@ mod tests {
mod benches { mod benches {
use test::{black_box, Bencher}; use test::{black_box, Bencher};
use io::sink;
use super::Block; use super::Block;
use crate::consensus::{deserialize, Decodable, Encodable}; use crate::consensus::{deserialize, Decodable, Encodable};
use crate::io::sink;
#[bench] #[bench]
pub fn bench_stream_reader(bh: &mut Bencher) { pub fn bench_stream_reader(bh: &mut Bencher) {

View File

@ -10,6 +10,7 @@ use core::cmp::{Ordering, PartialOrd};
use core::{fmt, mem}; use core::{fmt, mem};
use internals::write_err; use internals::write_err;
use io::{Read, Write};
#[cfg(all(test, mutate))] #[cfg(all(test, mutate))]
use mutagen::mutate; use mutagen::mutate;
@ -17,7 +18,6 @@ use mutagen::mutate;
use crate::absolute; use crate::absolute;
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
use crate::error::ParseIntError; use crate::error::ParseIntError;
use crate::io::{self, Read, Write};
use crate::parse::{impl_parse_str_from_int_fallible, impl_parse_str_from_int_infallible}; use crate::parse::{impl_parse_str_from_int_fallible, impl_parse_str_from_int_infallible};
use crate::prelude::*; use crate::prelude::*;
use crate::string::FromHexStr; use crate::string::FromHexStr;

View File

@ -31,7 +31,7 @@ use crate::script::Push;
#[cfg(doc)] #[cfg(doc)]
use crate::sighash::{EcdsaSighashType, TapSighashType}; use crate::sighash::{EcdsaSighashType, TapSighashType};
use crate::string::FromHexStr; use crate::string::FromHexStr;
use crate::{io, Amount, VarInt}; use crate::{Amount, VarInt};
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
#[cfg(feature = "bitcoinconsensus")] #[cfg(feature = "bitcoinconsensus")]
@ -2207,11 +2207,11 @@ mod tests {
#[cfg(bench)] #[cfg(bench)]
mod benches { mod benches {
use hex_lit::hex; use hex_lit::hex;
use io::sink;
use test::{black_box, Bencher}; use test::{black_box, Bencher};
use super::Transaction; use super::Transaction;
use crate::consensus::{deserialize, Encodable}; use crate::consensus::{deserialize, Encodable};
use crate::io::sink;
const SOME_TX: &str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; const SOME_TX: &str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";

View File

@ -8,10 +8,11 @@
use core::fmt; use core::fmt;
use core::ops::Index; use core::ops::Index;
use io::{Read, Write};
use crate::consensus::encode::{Error, MAX_VEC_SIZE}; use crate::consensus::encode::{Error, MAX_VEC_SIZE};
use crate::consensus::{Decodable, Encodable, WriteExt}; use crate::consensus::{Decodable, Encodable, WriteExt};
use crate::crypto::ecdsa; use crate::crypto::ecdsa;
use crate::io::{self, Read, Write};
use crate::prelude::*; use crate::prelude::*;
use crate::taproot::TAPROOT_ANNEX_PREFIX; use crate::taproot::TAPROOT_ANNEX_PREFIX;
use crate::{Script, VarInt}; use crate::{Script, VarInt};

View File

@ -20,12 +20,12 @@ use core::{fmt, mem, u32};
use hashes::{sha256, sha256d, Hash}; use hashes::{sha256, sha256d, Hash};
use internals::write_err; use internals::write_err;
use io::{Cursor, Read};
use crate::bip152::{PrefilledTransaction, ShortId}; use crate::bip152::{PrefilledTransaction, ShortId};
use crate::blockdata::block; use crate::blockdata::block;
use crate::blockdata::transaction::{Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{Transaction, TxIn, TxOut};
use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode}; use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode};
use crate::io::{self, Cursor, Read};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::p2p::{ use crate::p2p::{
address::{AddrV2Message, Address}, address::{AddrV2Message, Address},

View File

@ -18,7 +18,6 @@ use serde::{Deserializer, Serializer};
use super::encode::Error as ConsensusError; use super::encode::Error as ConsensusError;
use super::{Decodable, Encodable}; use super::{Decodable, Encodable};
use crate::io;
/// Hex-encoding strategy /// Hex-encoding strategy
pub struct Hex<Case = hex::Lower>(PhantomData<Case>) pub struct Hex<Case = hex::Lower>(PhantomData<Case>)

View File

@ -74,6 +74,9 @@ pub extern crate hashes;
/// Re-export the `hex-conservative` crate. /// Re-export the `hex-conservative` crate.
pub extern crate hex; pub extern crate hex;
/// Re-export the `bitcoin-io` crate.
pub extern crate io;
/// Rust wrapper library for Pieter Wuille's libsecp256k1. Implements ECDSA and BIP 340 signatures /// Rust wrapper library for Pieter Wuille's libsecp256k1. Implements ECDSA and BIP 340 signatures
/// for the SECG elliptic curve group secp256k1 and related utilities. /// for the SECG elliptic curve group secp256k1 and related utilities.
pub extern crate secp256k1; pub extern crate secp256k1;
@ -113,7 +116,6 @@ pub mod sign_message;
pub mod string; pub mod string;
pub mod taproot; pub mod taproot;
use bitcoin_io::io;
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)] #[doc(inline)]

View File

@ -48,7 +48,6 @@ use crate::blockdata::transaction::Transaction;
use crate::blockdata::weight::Weight; use crate::blockdata::weight::Weight;
use crate::consensus::encode::{self, Decodable, Encodable}; use crate::consensus::encode::{self, Decodable, Encodable};
use crate::hash_types::{TxMerkleNode, Txid}; use crate::hash_types::{TxMerkleNode, Txid};
use crate::io;
use crate::prelude::*; use crate::prelude::*;
/// Data structure that represents a block header paired to a partial merkle tree. /// Data structure that represents a block header paired to a partial merkle tree.

View File

@ -21,7 +21,6 @@ use core::iter;
use hashes::Hash; use hashes::Hash;
use crate::consensus::encode::Encodable; use crate::consensus::encode::Encodable;
use crate::io;
use crate::prelude::*; use crate::prelude::*;
#[rustfmt::skip] #[rustfmt::skip]

View File

@ -10,7 +10,6 @@ use core::{fmt, iter};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt}; use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt};
use crate::io;
use crate::p2p::ServiceFlags; use crate::p2p::ServiceFlags;
use crate::prelude::*; use crate::prelude::*;

View File

@ -12,7 +12,6 @@ use hashes::{sha256d, Hash};
use crate::blockdata::{block, transaction}; use crate::blockdata::{block, transaction};
use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt}; use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt};
use crate::io;
use crate::merkle_tree::MerkleBlock; use crate::merkle_tree::MerkleBlock;
use crate::p2p::address::{AddrV2Message, Address}; use crate::p2p::address::{AddrV2Message, Address};
use crate::p2p::{ use crate::p2p::{

View File

@ -7,7 +7,6 @@
use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::consensus::{encode, Decodable, Encodable, ReadExt};
use crate::internal_macros::impl_consensus_encoding; use crate::internal_macros::impl_consensus_encoding;
use crate::io;
/// `filterload` message sets the current bloom filter /// `filterload` message sets the current bloom filter
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]

View File

@ -9,6 +9,7 @@
use core::fmt::{self, LowerHex, UpperHex}; use core::fmt::{self, LowerHex, UpperHex};
use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub}; use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub};
use io::{Read, Write};
#[cfg(all(test, mutate))] #[cfg(all(test, mutate))]
use mutagen::mutate; use mutagen::mutate;
@ -16,7 +17,6 @@ use crate::consensus::encode::{self, Decodable, Encodable};
#[cfg(doc)] #[cfg(doc)]
use crate::consensus::Params; use crate::consensus::Params;
use crate::hash_types::BlockHash; use crate::hash_types::BlockHash;
use crate::io::{self, Read, Write};
use crate::prelude::String; use crate::prelude::String;
use crate::string::FromHexStr; use crate::string::FromHexStr;
use crate::Network; use crate::Network;

View File

@ -1,10 +1,11 @@
// SPDX-License-Identifier: CC0-1.0 // SPDX-License-Identifier: CC0-1.0
use io::{Cursor, Read};
use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub}; use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub};
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::Transaction;
use crate::consensus::encode::MAX_VEC_SIZE; use crate::consensus::encode::MAX_VEC_SIZE;
use crate::consensus::{encode, Decodable}; use crate::consensus::{encode, Decodable};
use crate::io::{self, Cursor, Read};
use crate::prelude::*; use crate::prelude::*;
use crate::psbt::map::Map; use crate::psbt::map::Map;
use crate::psbt::{raw, Error, Psbt}; use crate::psbt::{raw, Error, Psbt};

View File

@ -12,7 +12,6 @@ use super::serialize::{Deserialize, Serialize};
use crate::consensus::encode::{ use crate::consensus::encode::{
self, deserialize, serialize, Decodable, Encodable, ReadExt, VarInt, WriteExt, MAX_VEC_SIZE, self, deserialize, serialize, Decodable, Encodable, ReadExt, VarInt, WriteExt, MAX_VEC_SIZE,
}; };
use crate::io;
use crate::prelude::*; use crate::prelude::*;
use crate::psbt::Error; use crate::psbt::Error;

View File

@ -10,7 +10,7 @@ extern crate bitcoin_hashes;
#[cfg(feature = "alloc")] use alloc::string::ToString; #[cfg(feature = "alloc")] use alloc::string::ToString;
use bitcoin_hashes::{sha256, Hash, HashEngine}; use bitcoin_hashes::{sha256, Hash, HashEngine};
use bitcoin_io::io::Write; use bitcoin_io::Write;
use core::str::FromStr; use core::str::FromStr;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln}; use cortex_m_semihosting::{debug, hprintln};

View File

@ -66,7 +66,7 @@ impl_write!(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bitcoin_io::io::Write; use bitcoin_io::Write;
use crate::{hash160, hmac, ripemd160, sha1, sha256, sha256d, sha512, siphash24, Hash}; use crate::{hash160, hmac, ripemd160, sha1, sha256, sha256d, sha512, siphash24, Hash};

View File

@ -20,9 +20,10 @@
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
extern crate alloc; extern crate alloc;
mod macros;
/// Standard I/O stream definitions which are API-equivalent to `std`'s `io` module. See /// Standard I/O stream definitions which are API-equivalent to `std`'s `io` module. See
/// [`std::io`] for more info. /// [`std::io`] for more info.
pub mod io {
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use alloc::boxed::Box; use alloc::boxed::Box;
use core::convert::TryInto; use core::convert::TryInto;
@ -349,57 +350,4 @@ pub mod io {
} }
/// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info. /// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info.
pub fn sink() -> Sink { Sink } pub fn sink() -> Sink { Sink }
}
#[doc(hidden)]
#[cfg(feature = "std")]
/// Re-export std for the below macro
pub use std as _std;
#[macro_export]
/// Because we cannot provide a blanket implementation of [`std::io::Write`] for all implementers
/// of this crate's `io::Write` trait, we provide this macro instead.
///
/// This macro will implement `Write` given a `write` and `flush` fn, either by implementing the
/// crate's native `io::Write` trait directly, or a more generic trait from `std` for users using
/// that feature. In any case, this crate's `io::Write` feature will be implemented for the given
/// type, even if indirectly.
#[cfg(not(feature = "std"))]
macro_rules! impl_write {
($ty: ty, $write_fn: expr, $flush_fn: expr $(, $bounded_ty: ident : $bounds: path),*) => {
impl<$($bounded_ty: $bounds),*> $crate::io::Write for $ty {
#[inline]
fn write(&mut self, buf: &[u8]) -> $crate::io::Result<usize> {
$write_fn(self, buf)
}
#[inline]
fn flush(&mut self) -> $crate::io::Result<()> {
$flush_fn(self)
}
}
}
}
#[macro_export]
/// Because we cannot provide a blanket implementation of [`std::io::Write`] for all implementers
/// of this crate's `io::Write` trait, we provide this macro instead.
///
/// This macro will implement `Write` given a `write` and `flush` fn, either by implementing the
/// crate's native `io::Write` trait directly, or a more generic trait from `std` for users using
/// that feature. In any case, this crate's `io::Write` feature will be implemented for the given
/// type, even if indirectly.
#[cfg(feature = "std")]
macro_rules! impl_write {
($ty: ty, $write_fn: expr, $flush_fn: expr $(, $bounded_ty: ident : $bounds: path),*) => {
impl<$($bounded_ty: $bounds),*> $crate::_std::io::Write for $ty {
#[inline]
fn write(&mut self, buf: &[u8]) -> $crate::_std::io::Result<usize> {
$write_fn(self, buf)
}
#[inline]
fn flush(&mut self) -> $crate::_std::io::Result<()> {
$flush_fn(self)
}
}
}
}

49
io/src/macros.rs Normal file
View File

@ -0,0 +1,49 @@
//! Public macros for porvide.d for users to be able implement our `io::Write` trait.
#[macro_export]
/// Because we cannot provide a blanket implementation of [`std::io::Write`] for all implementers
/// of this crate's `io::Write` trait, we provide this macro instead.
///
/// This macro will implement `Write` given a `write` and `flush` fn, either by implementing the
/// crate's native `io::Write` trait directly, or a more generic trait from `std` for users using
/// that feature. In any case, this crate's `io::Write` feature will be implemented for the given
/// type, even if indirectly.
#[cfg(not(feature = "std"))]
macro_rules! impl_write {
($ty: ty, $write_fn: expr, $flush_fn: expr $(, $bounded_ty: ident : $bounds: path),*) => {
impl<$($bounded_ty: $bounds),*> $crate::Write for $ty {
#[inline]
fn write(&mut self, buf: &[u8]) -> $crate::Result<usize> {
$write_fn(self, buf)
}
#[inline]
fn flush(&mut self) -> $crate::Result<()> {
$flush_fn(self)
}
}
}
}
#[macro_export]
/// Because we cannot provide a blanket implementation of [`std::io::Write`] for all implementers
/// of this crate's `io::Write` trait, we provide this macro instead.
///
/// This macro will implement `Write` given a `write` and `flush` fn, either by implementing the
/// crate's native `io::Write` trait directly, or a more generic trait from `std` for users using
/// that feature. In any case, this crate's `io::Write` feature will be implemented for the given
/// type, even if indirectly.
#[cfg(feature = "std")]
macro_rules! impl_write {
($ty: ty, $write_fn: expr, $flush_fn: expr $(, $bounded_ty: ident : $bounds: path),*) => {
impl<$($bounded_ty: $bounds),*> std::io::Write for $ty {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
$write_fn(self, buf)
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
$flush_fn(self)
}
}
}
}