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: ACKf764a607ac
Kixunil: ACKf764a607ac
Tree-SHA512: 38888b0c23d5f2cd874f77dd332fe4fa4b9acb90e3a2dac19e62ed3d98151acd7480c719aa85434e1a3de987af2c4f565528a914a14d5fd3f0f0e410cbdf5d40
This commit is contained in:
commit
a3f6f53d37
|
@ -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 }
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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>)
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
||||||
|
|
|
@ -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::{
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
200
io/src/lib.rs
200
io/src/lib.rs
|
@ -20,16 +20,17 @@
|
||||||
#[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;
|
use core::fmt::{Debug, Display, Formatter};
|
||||||
use core::fmt::{Debug, Display, Formatter};
|
|
||||||
|
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
mod sealed {
|
mod sealed {
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
@ -42,18 +43,18 @@ pub mod io {
|
||||||
impl IntoBoxDynDebug for String {
|
impl IntoBoxDynDebug for String {
|
||||||
fn into(self) -> Box<dyn Debug + Send + Sync + 'static> { Box::new(self) }
|
fn into(self) -> Box<dyn Debug + Send + Sync + 'static> { Box::new(self) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
kind: ErrorKind,
|
kind: ErrorKind,
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
error: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
|
error: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
error: Option<Box<dyn Debug + Send + Sync + 'static>>,
|
error: Option<Box<dyn Debug + Send + Sync + 'static>>,
|
||||||
}
|
}
|
||||||
impl Error {
|
impl 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
|
||||||
|
@ -67,9 +68,9 @@ pub mod io {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> ErrorKind { self.kind }
|
pub fn kind(&self) -> ErrorKind { self.kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ErrorKind> for Error {
|
impl From<ErrorKind> for Error {
|
||||||
fn from(kind: ErrorKind) -> Error {
|
fn from(kind: ErrorKind) -> Error {
|
||||||
Self {
|
Self {
|
||||||
kind,
|
kind,
|
||||||
|
@ -77,9 +78,9 @@ pub mod io {
|
||||||
error: None,
|
error: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> core::result::Result<(), core::fmt::Error> {
|
fn fmt(&self, fmt: &mut Formatter) -> core::result::Result<(), core::fmt::Error> {
|
||||||
fmt.write_fmt(format_args!("I/O Error: {}", self.kind.description()))?;
|
fmt.write_fmt(format_args!("I/O Error: {}", self.kind.description()))?;
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
|
@ -88,10 +89,10 @@ pub mod io {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl std::error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
self.error.as_ref().and_then(|e| e.as_ref().source())
|
self.error.as_ref().and_then(|e| e.as_ref().source())
|
||||||
}
|
}
|
||||||
|
@ -106,9 +107,9 @@ pub mod io {
|
||||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||||
self.error.as_ref().and_then(|e| e.as_ref().cause())
|
self.error.as_ref().and_then(|e| e.as_ref().cause())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl 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()
|
||||||
|
@ -117,17 +118,17 @@ pub mod io {
|
||||||
pub fn get_ref(&self) -> Option<&(dyn Debug + Send + Sync + 'static)> {
|
pub fn get_ref(&self) -> Option<&(dyn Debug + Send + Sync + 'static)> {
|
||||||
self.error.as_deref()
|
self.error.as_deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl From<std::io::Error> for Error {
|
impl From<std::io::Error> for Error {
|
||||||
fn from(o: std::io::Error) -> Error {
|
fn from(o: std::io::Error) -> Error {
|
||||||
Self { kind: ErrorKind::from_std(o.kind()), error: o.into_inner() }
|
Self { kind: ErrorKind::from_std(o.kind()), error: o.into_inner() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl From<Error> for std::io::Error {
|
impl From<Error> for std::io::Error {
|
||||||
fn from(o: Error) -> std::io::Error {
|
fn from(o: Error) -> std::io::Error {
|
||||||
if let Some(err) = o.error {
|
if let Some(err) = o.error {
|
||||||
std::io::Error::new(o.kind.to_std(), err)
|
std::io::Error::new(o.kind.to_std(), err)
|
||||||
|
@ -135,9 +136,9 @@ pub mod io {
|
||||||
o.kind.to_std().into()
|
o.kind.to_std().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! define_errorkind {
|
macro_rules! define_errorkind {
|
||||||
($($kind: ident),*) => {
|
($($kind: ident),*) => {
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||||
|
@ -170,9 +171,9 @@ pub mod io {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define_errorkind!(
|
define_errorkind!(
|
||||||
NotFound,
|
NotFound,
|
||||||
PermissionDenied,
|
PermissionDenied,
|
||||||
ConnectionRefused,
|
ConnectionRefused,
|
||||||
|
@ -192,12 +193,12 @@ pub mod io {
|
||||||
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!
|
||||||
Other
|
Other
|
||||||
);
|
);
|
||||||
|
|
||||||
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 {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
|
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
|
||||||
|
@ -213,13 +214,13 @@ pub mod io {
|
||||||
}
|
}
|
||||||
#[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 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
impl<'a, R: Read + ?Sized> Read for Take<'a, R> {
|
impl<'a, R: Read + ?Sized> Read for Take<'a, R> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let len = core::cmp::min(buf.len(), self.remaining.try_into().unwrap_or(buf.len()));
|
let len = core::cmp::min(buf.len(), self.remaining.try_into().unwrap_or(buf.len()));
|
||||||
|
@ -227,18 +228,18 @@ pub mod io {
|
||||||
self.remaining -= read.try_into().unwrap_or(self.remaining);
|
self.remaining -= read.try_into().unwrap_or(self.remaining);
|
||||||
Ok(read)
|
Ok(read)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<R: std::io::Read> Read for R {
|
impl<R: std::io::Read> Read for R {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
Ok(<R as std::io::Read>::read(self, buf)?)
|
Ok(<R as std::io::Read>::read(self, buf)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
impl Read for &[u8] {
|
impl Read for &[u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let cnt = core::cmp::min(self.len(), buf.len());
|
let cnt = core::cmp::min(self.len(), buf.len());
|
||||||
|
@ -246,21 +247,21 @@ pub mod io {
|
||||||
*self = &self[cnt..];
|
*self = &self[cnt..];
|
||||||
Ok(cnt)
|
Ok(cnt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } }
|
pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn position(&self) -> u64 { self.pos }
|
pub fn position(&self) -> u64 { self.pos }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_inner(self) -> T { self.inner }
|
pub fn into_inner(self) -> T { self.inner }
|
||||||
}
|
}
|
||||||
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let inner: &[u8] = self.inner.as_ref();
|
let inner: &[u8] = self.inner.as_ref();
|
||||||
|
@ -272,10 +273,10 @@ pub mod io {
|
||||||
.saturating_add(read.try_into().unwrap_or(u64::max_value() /* unreachable */));
|
.saturating_add(read.try_into().unwrap_or(u64::max_value() /* unreachable */));
|
||||||
Ok(read)
|
Ok(read)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
||||||
fn flush(&mut self) -> Result<()>;
|
fn flush(&mut self) -> Result<()>;
|
||||||
|
|
||||||
|
@ -291,20 +292,20 @@ pub mod io {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<W: std::io::Write> Write for W {
|
impl<W: std::io::Write> Write for W {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
Ok(<W as std::io::Write>::write(self, buf)?)
|
Ok(<W as std::io::Write>::write(self, buf)?)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<()> { Ok(<W as std::io::Write>::flush(self)?) }
|
fn flush(&mut self) -> Result<()> { Ok(<W as std::io::Write>::flush(self)?) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
impl Write for alloc::vec::Vec<u8> {
|
impl Write for alloc::vec::Vec<u8> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
self.extend_from_slice(buf);
|
self.extend_from_slice(buf);
|
||||||
|
@ -312,10 +313,10 @@ pub mod io {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<()> { Ok(()) }
|
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
impl<'a> Write for &'a mut [u8] {
|
impl<'a> Write for &'a mut [u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
let cnt = core::cmp::min(self.len(), buf.len());
|
let cnt = core::cmp::min(self.len(), buf.len());
|
||||||
|
@ -325,81 +326,28 @@ pub mod io {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<()> { Ok(()) }
|
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
pub struct Sink;
|
pub struct Sink;
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
impl Write for Sink {
|
impl Write for Sink {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
|
fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
|
fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<()> { Ok(()) }
|
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||||
}
|
}
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl std::io::Write for Sink {
|
impl std::io::Write for Sink {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { Ok(buf.len()) }
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { Ok(buf.len()) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_all(&mut self, _: &[u8]) -> std::io::Result<()> { Ok(()) }
|
fn write_all(&mut self, _: &[u8]) -> std::io::Result<()> { Ok(()) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
|
fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
|
||||||
}
|
|
||||||
/// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info.
|
|
||||||
pub fn sink() -> Sink { Sink }
|
|
||||||
}
|
}
|
||||||
|
/// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info.
|
||||||
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue