Merge rust-bitcoin/rust-bitcoin#1040: Introduce rustfmt in a non-invasive manner
ee9a3ec6a1
Enable formatter for "src" (Tobin C. Harding)743b197124
Add use for Unexpected (Tobin C. Harding)fd217e72c3
Use f instead of formatter (Tobin C. Harding)7b50a96ade
Do not format prelude module (Tobin C. Harding)01471f7e65
Shield hash_newtypes from rustfmt (Tobin C. Harding)65d19d9044
Refactor compile_error message (Tobin C. Harding)6461e2db8d
Run formatter on examples/ (Tobin C. Harding)fd1c6589ba
Add a rustfmt configuration file with explicit ignores (Tobin C. Harding) Pull request description: Looks like we are getting to a place that rustfmt _might_ be able to be used. In an effort to introduce `rustfmt` without requiring devs to do excessively mundane reviews introduce `rustfmt` in a non-invasive manner. What this means is - Add a fully fleshed out `rustfmt` config file that explicitly ignores all the source files - Enable sections of code one by one so review is easier (including preparatory patches before doing each section). This PR currently does `examples` and all the source files at the root level of the crate (i.e. excludes all directories in `src/`). The other directories can then be done one at a time. Please see discussion on: https://github.com/rust-bitcoin/rust-bitcoin/pull/959 for more context. ACKs for top commit: sanket1729: ACKee9a3ec6a1
apoelstra: ACKee9a3ec6a1
Tree-SHA512: f4ff3c031b5d685777e09bac2df59ed8217576b807da7699f44fe00aa509d0b7fe47617a8b3eff00d3125aeece3e010b8f9dd8733d315ccb2adc0e9a7d7f07e3
This commit is contained in:
commit
e5acc07789
|
@ -1,17 +1,14 @@
|
||||||
extern crate bitcoin;
|
extern crate bitcoin;
|
||||||
|
|
||||||
use std::{env, process};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::{env, process};
|
||||||
|
|
||||||
use bitcoin::secp256k1::Secp256k1;
|
|
||||||
use bitcoin::PublicKey;
|
|
||||||
use bitcoin::util::bip32::ExtendedPrivKey;
|
|
||||||
use bitcoin::util::bip32::ExtendedPubKey;
|
|
||||||
use bitcoin::util::bip32::DerivationPath;
|
|
||||||
use bitcoin::util::bip32::ChildNumber;
|
|
||||||
use bitcoin::util::address::Address;
|
|
||||||
use bitcoin::secp256k1::ffi::types::AlignedType;
|
|
||||||
use bitcoin::hashes::hex::FromHex;
|
use bitcoin::hashes::hex::FromHex;
|
||||||
|
use bitcoin::secp256k1::ffi::types::AlignedType;
|
||||||
|
use bitcoin::secp256k1::Secp256k1;
|
||||||
|
use bitcoin::util::address::Address;
|
||||||
|
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey};
|
||||||
|
use bitcoin::PublicKey;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// This example derives root xprv from a 32-byte seed,
|
// This example derives root xprv from a 32-byte seed,
|
||||||
|
@ -55,10 +52,7 @@ fn main() {
|
||||||
// generate first receiving address at m/0/0
|
// generate first receiving address at m/0/0
|
||||||
// manually creating indexes this time
|
// manually creating indexes this time
|
||||||
let zero = ChildNumber::from_normal_idx(0).unwrap();
|
let zero = ChildNumber::from_normal_idx(0).unwrap();
|
||||||
let public_key = xpub.derive_pub(&secp, &vec![zero, zero])
|
let public_key = xpub.derive_pub(&secp, &vec![zero, zero]).unwrap().public_key;
|
||||||
.unwrap()
|
|
||||||
.public_key;
|
|
||||||
let address = Address::p2wpkh(&PublicKey::new(public_key), network).unwrap();
|
let address = Address::p2wpkh(&PublicKey::new(public_key), network).unwrap();
|
||||||
println!("First receiving address: {}", address);
|
println!("First receiving address: {}", address);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
extern crate bitcoin;
|
extern crate bitcoin;
|
||||||
|
|
||||||
|
use std::io::{BufReader, Write};
|
||||||
use std::net::{IpAddr, Ipv4Addr, Shutdown, SocketAddr, TcpStream};
|
use std::net::{IpAddr, Ipv4Addr, Shutdown, SocketAddr, TcpStream};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use std::{env, process};
|
use std::{env, process};
|
||||||
use std::io::{Write, BufReader};
|
|
||||||
|
|
||||||
use bitcoin::consensus::{encode, Decodable};
|
use bitcoin::consensus::{encode, Decodable};
|
||||||
use bitcoin::network::{address, constants, message, message_network};
|
use bitcoin::network::{address, constants, message, message_network};
|
||||||
|
@ -80,10 +80,7 @@ fn build_version_message(address: SocketAddr) -> message::NetworkMessage {
|
||||||
let services = constants::ServiceFlags::NONE;
|
let services = constants::ServiceFlags::NONE;
|
||||||
|
|
||||||
// "standard UNIX timestamp in seconds"
|
// "standard UNIX timestamp in seconds"
|
||||||
let timestamp = SystemTime::now()
|
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time error").as_secs();
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.expect("Time error")
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
// "The network address of the node receiving this message"
|
// "The network address of the node receiving this message"
|
||||||
let addr_recv = address::Address::new(&address, constants::ServiceFlags::NONE);
|
let addr_recv = address::Address::new(&address, constants::ServiceFlags::NONE);
|
||||||
|
|
86
rustfmt.toml
86
rustfmt.toml
|
@ -1 +1,85 @@
|
||||||
disable_all_formatting = true
|
# Eventually this shoud be: ignore = []
|
||||||
|
ignore = [
|
||||||
|
"src/blockdata",
|
||||||
|
"src/consensus",
|
||||||
|
"src/network",
|
||||||
|
"src/util",
|
||||||
|
]
|
||||||
|
|
||||||
|
hard_tabs = false
|
||||||
|
tab_spaces = 4
|
||||||
|
newline_style = "Auto"
|
||||||
|
indent_style = "Block"
|
||||||
|
|
||||||
|
max_width = 100 # This is number of characters.
|
||||||
|
# `use_small_heuristics` is ignored if the granular width config values are explicitly set.
|
||||||
|
use_small_heuristics = "Max" # "Max" == All granular width settings same as `max_width`.
|
||||||
|
# # Granular width configuration settings. These are percentages of `max_width`.
|
||||||
|
# fn_call_width = 60
|
||||||
|
# attr_fn_like_width = 70
|
||||||
|
# struct_lit_width = 18
|
||||||
|
# struct_variant_width = 35
|
||||||
|
# array_width = 60
|
||||||
|
# chain_width = 60
|
||||||
|
# single_line_if_else_max_width = 50
|
||||||
|
|
||||||
|
wrap_comments = false
|
||||||
|
format_code_in_doc_comments = false
|
||||||
|
comment_width = 100 # Default 80
|
||||||
|
normalize_comments = false
|
||||||
|
normalize_doc_attributes = false
|
||||||
|
format_strings = false
|
||||||
|
format_macro_matchers = false
|
||||||
|
format_macro_bodies = true
|
||||||
|
hex_literal_case = "Preserve"
|
||||||
|
empty_item_single_line = true
|
||||||
|
struct_lit_single_line = true
|
||||||
|
fn_single_line = true # Default false
|
||||||
|
where_single_line = false
|
||||||
|
imports_indent = "Block"
|
||||||
|
imports_layout = "Mixed"
|
||||||
|
imports_granularity = "Module" # Default "Preserve"
|
||||||
|
group_imports = "StdExternalCrate" # Default "Preserve"
|
||||||
|
reorder_imports = true
|
||||||
|
reorder_modules = true
|
||||||
|
reorder_impl_items = false
|
||||||
|
type_punctuation_density = "Wide"
|
||||||
|
space_before_colon = false
|
||||||
|
space_after_colon = true
|
||||||
|
spaces_around_ranges = false
|
||||||
|
binop_separator = "Front"
|
||||||
|
remove_nested_parens = true
|
||||||
|
combine_control_expr = true
|
||||||
|
overflow_delimited_expr = false
|
||||||
|
struct_field_align_threshold = 0
|
||||||
|
enum_discrim_align_threshold = 0
|
||||||
|
match_arm_blocks = false # Default true
|
||||||
|
match_arm_leading_pipes = "Never"
|
||||||
|
force_multiline_blocks = false
|
||||||
|
fn_args_layout = "Tall"
|
||||||
|
brace_style = "SameLineWhere"
|
||||||
|
control_brace_style = "AlwaysSameLine"
|
||||||
|
trailing_semicolon = true
|
||||||
|
trailing_comma = "Vertical"
|
||||||
|
match_block_trailing_comma = false
|
||||||
|
blank_lines_upper_bound = 1
|
||||||
|
blank_lines_lower_bound = 0
|
||||||
|
edition = "2018"
|
||||||
|
version = "One"
|
||||||
|
inline_attribute_width = 0
|
||||||
|
format_generated_files = true
|
||||||
|
merge_derives = true
|
||||||
|
use_try_shorthand = false
|
||||||
|
use_field_init_shorthand = false
|
||||||
|
force_explicit_abi = true
|
||||||
|
condense_wildcard_suffixes = false
|
||||||
|
color = "Auto"
|
||||||
|
required_version = "1.5.1"
|
||||||
|
unstable_features = false
|
||||||
|
disable_all_formatting = false
|
||||||
|
skip_children = false
|
||||||
|
hide_parse_errors = false
|
||||||
|
error_on_line_overflow = false
|
||||||
|
error_on_unformatted = false
|
||||||
|
emit_mode = "Files"
|
||||||
|
make_backup = false
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
//! hash).
|
//! hash).
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use bitcoin_hashes::{sha256, sha256d, hash160, hash_newtype};
|
#[rustfmt::skip]
|
||||||
|
|
||||||
macro_rules! impl_hashencode {
|
macro_rules! impl_hashencode {
|
||||||
($hashtype:ident) => {
|
($hashtype:ident) => {
|
||||||
impl $crate::consensus::Encodable for $hashtype {
|
impl $crate::consensus::Encodable for $hashtype {
|
||||||
|
@ -25,11 +24,18 @@ macro_rules! impl_hashencode {
|
||||||
Ok(Self::from_inner(<<$hashtype as $crate::hashes::Hash>::Inner>::consensus_decode(r)?))
|
Ok(Self::from_inner(<<$hashtype as $crate::hashes::Hash>::Inner>::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_newtype!(
|
// newtypes module is solely here so we can rustfmt::skip.
|
||||||
Txid, sha256d::Hash, 32, doc="A bitcoin transaction hash/transaction ID.
|
pub use newtypes::*;
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
mod newtypes {
|
||||||
|
use crate::hashes::{sha256, sha256d, hash160, hash_newtype};
|
||||||
|
|
||||||
|
hash_newtype!(
|
||||||
|
Txid, sha256d::Hash, 32, doc="A bitcoin transaction hash/transaction ID.
|
||||||
|
|
||||||
For compatibility with the existing Bitcoin infrastructure and historical
|
For compatibility with the existing Bitcoin infrastructure and historical
|
||||||
and current versions of the Bitcoin Core software itself, this and
|
and current versions of the Bitcoin Core software itself, this and
|
||||||
|
@ -37,31 +43,31 @@ other [`sha256d::Hash`] types, are serialized in reverse
|
||||||
byte order when converted to a hex string via [`std::fmt::Display`] trait operations.
|
byte order when converted to a hex string via [`std::fmt::Display`] trait operations.
|
||||||
See [`hashes::Hash::DISPLAY_BACKWARD`] for more details.
|
See [`hashes::Hash::DISPLAY_BACKWARD`] for more details.
|
||||||
");
|
");
|
||||||
hash_newtype!(Wtxid, sha256d::Hash, 32, doc="A bitcoin witness transaction ID.");
|
hash_newtype!(Wtxid, sha256d::Hash, 32, doc="A bitcoin witness transaction ID.");
|
||||||
hash_newtype!(BlockHash, sha256d::Hash, 32, doc="A bitcoin block hash.");
|
hash_newtype!(BlockHash, sha256d::Hash, 32, doc="A bitcoin block hash.");
|
||||||
hash_newtype!(Sighash, sha256d::Hash, 32, doc="Hash of the transaction according to the signature algorithm");
|
hash_newtype!(Sighash, sha256d::Hash, 32, doc="Hash of the transaction according to the signature algorithm");
|
||||||
|
|
||||||
hash_newtype!(PubkeyHash, hash160::Hash, 20, doc="A hash of a public key.");
|
hash_newtype!(PubkeyHash, hash160::Hash, 20, doc="A hash of a public key.");
|
||||||
hash_newtype!(ScriptHash, hash160::Hash, 20, doc="A hash of Bitcoin Script bytecode.");
|
hash_newtype!(ScriptHash, hash160::Hash, 20, doc="A hash of Bitcoin Script bytecode.");
|
||||||
hash_newtype!(WPubkeyHash, hash160::Hash, 20, doc="SegWit version of a public key hash.");
|
hash_newtype!(WPubkeyHash, hash160::Hash, 20, doc="SegWit version of a public key hash.");
|
||||||
hash_newtype!(WScriptHash, sha256::Hash, 32, doc="SegWit version of a Bitcoin Script bytecode hash.");
|
hash_newtype!(WScriptHash, sha256::Hash, 32, doc="SegWit version of a Bitcoin Script bytecode hash.");
|
||||||
|
|
||||||
hash_newtype!(TxMerkleNode, sha256d::Hash, 32, doc="A hash of the Merkle tree branch or root for transactions");
|
hash_newtype!(TxMerkleNode, sha256d::Hash, 32, doc="A hash of the Merkle tree branch or root for transactions");
|
||||||
hash_newtype!(WitnessMerkleNode, sha256d::Hash, 32, doc="A hash corresponding to the Merkle tree root for witness data");
|
hash_newtype!(WitnessMerkleNode, sha256d::Hash, 32, doc="A hash corresponding to the Merkle tree root for witness data");
|
||||||
hash_newtype!(WitnessCommitment, sha256d::Hash, 32, doc="A hash corresponding to the witness structure commitment in the coinbase transaction");
|
hash_newtype!(WitnessCommitment, sha256d::Hash, 32, doc="A hash corresponding to the witness structure commitment in the coinbase transaction");
|
||||||
hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32.");
|
hash_newtype!(XpubIdentifier, hash160::Hash, 20, doc="XpubIdentifier as defined in BIP-32.");
|
||||||
|
|
||||||
hash_newtype!(FilterHash, sha256d::Hash, 32, doc="Filter hash, as defined in BIP-157");
|
hash_newtype!(FilterHash, sha256d::Hash, 32, doc="Filter hash, as defined in BIP-157");
|
||||||
hash_newtype!(FilterHeader, sha256d::Hash, 32, doc="Filter header, as defined in BIP-157");
|
hash_newtype!(FilterHeader, sha256d::Hash, 32, doc="Filter header, as defined in BIP-157");
|
||||||
|
|
||||||
|
impl_hashencode!(Txid);
|
||||||
|
impl_hashencode!(Wtxid);
|
||||||
|
impl_hashencode!(BlockHash);
|
||||||
|
impl_hashencode!(Sighash);
|
||||||
|
|
||||||
impl_hashencode!(Txid);
|
impl_hashencode!(TxMerkleNode);
|
||||||
impl_hashencode!(Wtxid);
|
impl_hashencode!(WitnessMerkleNode);
|
||||||
impl_hashencode!(BlockHash);
|
|
||||||
impl_hashencode!(Sighash);
|
|
||||||
|
|
||||||
impl_hashencode!(TxMerkleNode);
|
impl_hashencode!(FilterHash);
|
||||||
impl_hashencode!(WitnessMerkleNode);
|
impl_hashencode!(FilterHeader);
|
||||||
|
}
|
||||||
impl_hashencode!(FilterHash);
|
|
||||||
impl_hashencode!(FilterHeader);
|
|
||||||
|
|
|
@ -100,11 +100,9 @@ macro_rules! impl_array_newtype {
|
||||||
type Output = <[$ty] as core::ops::Index<I>>::Output;
|
type Output = <[$ty] as core::ops::Index<I>>::Output;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: I) -> &Self::Output {
|
fn index(&self, index: I) -> &Self::Output { &self.0[index] }
|
||||||
&self.0[index]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! display_from_debug {
|
macro_rules! display_from_debug {
|
||||||
|
@ -114,7 +112,7 @@ macro_rules! display_from_debug {
|
||||||
core::fmt::Debug::fmt(self, f)
|
core::fmt::Debug::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -142,8 +140,8 @@ macro_rules! serde_string_impl {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str($expecting)
|
f.write_str($expecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
@ -190,8 +188,8 @@ macro_rules! serde_struct_human_string_impl {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str($expecting)
|
f.write_str($expecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
@ -215,8 +213,8 @@ macro_rules! serde_struct_human_string_impl {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for EnumVisitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for EnumVisitor {
|
||||||
type Value = Enum;
|
type Value = Enum;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a field name")
|
f.write_str("a field name")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
@ -246,8 +244,8 @@ macro_rules! serde_struct_human_string_impl {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a struct")
|
f.write_str("a struct")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
||||||
|
@ -352,8 +350,7 @@ macro_rules! serde_struct_human_string_impl {
|
||||||
/// - core::str::FromStr
|
/// - core::str::FromStr
|
||||||
/// - hashes::hex::FromHex
|
/// - hashes::hex::FromHex
|
||||||
macro_rules! impl_bytes_newtype {
|
macro_rules! impl_bytes_newtype {
|
||||||
($t:ident, $len:literal) => (
|
($t:ident, $len:literal) => {
|
||||||
|
|
||||||
impl core::fmt::LowerHex for $t {
|
impl core::fmt::LowerHex for $t {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
for &ch in self.0.iter() {
|
for &ch in self.0.iter() {
|
||||||
|
@ -378,9 +375,9 @@ macro_rules! impl_bytes_newtype {
|
||||||
impl $crate::hashes::hex::FromHex for $t {
|
impl $crate::hashes::hex::FromHex for $t {
|
||||||
fn from_byte_iter<I>(iter: I) -> Result<Self, $crate::hashes::hex::Error>
|
fn from_byte_iter<I>(iter: I) -> Result<Self, $crate::hashes::hex::Error>
|
||||||
where
|
where
|
||||||
I: core::iter::Iterator<Item=Result<u8, $crate::hashes::hex::Error>>
|
I: core::iter::Iterator<Item = Result<u8, $crate::hashes::hex::Error>>
|
||||||
+ core::iter::ExactSizeIterator
|
+ core::iter::ExactSizeIterator
|
||||||
+ core::iter::DoubleEndedIterator,
|
+ core::iter::DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
if iter.len() == $len {
|
if iter.len() == $len {
|
||||||
let mut ret = [0; $len];
|
let mut ret = [0; $len];
|
||||||
|
@ -423,18 +420,20 @@ macro_rules! impl_bytes_newtype {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for HexVisitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for HexVisitor {
|
||||||
type Value = $t;
|
type Value = $t;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
formatter.write_str("an ASCII hex string")
|
f.write_str("an ASCII hex string")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: $crate::serde::de::Error,
|
E: $crate::serde::de::Error,
|
||||||
{
|
{
|
||||||
|
use $crate::serde::de::Unexpected;
|
||||||
|
|
||||||
if let Ok(hex) = core::str::from_utf8(v) {
|
if let Ok(hex) = core::str::from_utf8(v) {
|
||||||
$crate::hashes::hex::FromHex::from_hex(hex).map_err(E::custom)
|
$crate::hashes::hex::FromHex::from_hex(hex).map_err(E::custom)
|
||||||
} else {
|
} else {
|
||||||
return Err(E::invalid_value($crate::serde::de::Unexpected::Bytes(v), &self));
|
return Err(E::invalid_value(Unexpected::Bytes(v), &self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,8 +452,8 @@ macro_rules! impl_bytes_newtype {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for BytesVisitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for BytesVisitor {
|
||||||
type Value = $t;
|
type Value = $t;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
formatter.write_str("a bytestring")
|
f.write_str("a bytestring")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
|
@ -475,7 +474,7 @@ macro_rules! impl_bytes_newtype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! user_enum {
|
macro_rules! user_enum {
|
||||||
|
@ -531,8 +530,8 @@ macro_rules! user_enum {
|
||||||
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str("an enum value")
|
f.write_str("an enum value")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
@ -586,9 +585,7 @@ macro_rules! write_err {
|
||||||
|
|
||||||
/// Asserts a boolean expression at compile time.
|
/// Asserts a boolean expression at compile time.
|
||||||
macro_rules! const_assert {
|
macro_rules! const_assert {
|
||||||
($x:expr) => {
|
($x:expr) => {{
|
||||||
{
|
const _: [(); 0 - !$x as usize] = [];
|
||||||
const _: [(); 0 - !$x as usize] = [];
|
}};
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
121
src/lib.rs
121
src/lib.rs
|
@ -29,11 +29,9 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
|
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
|
||||||
|
|
||||||
// Experimental features we need.
|
// Experimental features we need.
|
||||||
#![cfg_attr(bench, feature(test))]
|
#![cfg_attr(bench, feature(test))]
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
// Coding conventions
|
// Coding conventions
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![deny(non_upper_case_globals)]
|
#![deny(non_upper_case_globals)]
|
||||||
|
@ -50,11 +48,13 @@ compile_error!("at least one of the `std` or `no-std` features must be enabled")
|
||||||
|
|
||||||
// Disable 16-bit support at least for now as we can't guarantee it yet.
|
// Disable 16-bit support at least for now as we can't guarantee it yet.
|
||||||
#[cfg(target_pointer_width = "16")]
|
#[cfg(target_pointer_width = "16")]
|
||||||
compile_error!("rust-bitcoin currently only supports architectures with pointers wider
|
compile_error!(
|
||||||
than 16 bits, let us know if you want 16-bit support. Note that we do
|
"rust-bitcoin currently only supports architectures with pointers wider than 16 bits, let us
|
||||||
NOT guarantee that we will implement it!");
|
know if you want 16-bit support. Note that we do NOT guarantee that we will implement it!"
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(bench)] extern crate test;
|
#[cfg(bench)]
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
#[cfg(feature = "no-std")]
|
#[cfg(feature = "no-std")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -63,9 +63,10 @@ extern crate alloc;
|
||||||
extern crate core2;
|
extern crate core2;
|
||||||
|
|
||||||
// Re-exported dependencies.
|
// Re-exported dependencies.
|
||||||
#[macro_use] pub extern crate bitcoin_hashes as hashes;
|
#[macro_use]
|
||||||
pub extern crate secp256k1;
|
pub extern crate bitcoin_hashes as hashes;
|
||||||
pub extern crate bech32;
|
pub extern crate bech32;
|
||||||
|
pub extern crate secp256k1;
|
||||||
|
|
||||||
#[cfg(feature = "no-std")]
|
#[cfg(feature = "no-std")]
|
||||||
extern crate hashbrown;
|
extern crate hashbrown;
|
||||||
|
@ -74,12 +75,19 @@ extern crate hashbrown;
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
||||||
pub extern crate base64;
|
pub extern crate base64;
|
||||||
|
|
||||||
#[cfg(feature="bitcoinconsensus")] extern crate bitcoinconsensus;
|
#[cfg(feature = "bitcoinconsensus")]
|
||||||
#[cfg(feature = "serde")] #[macro_use] extern crate actual_serde as serde;
|
extern crate bitcoinconsensus;
|
||||||
#[cfg(all(test, feature = "serde"))] extern crate serde_json;
|
#[cfg(feature = "serde")]
|
||||||
#[cfg(all(test, feature = "serde"))] extern crate serde_test;
|
#[macro_use]
|
||||||
#[cfg(all(test, feature = "serde"))] extern crate bincode;
|
extern crate actual_serde as serde;
|
||||||
#[cfg(all(test, feature = "unstable"))] extern crate test;
|
#[cfg(all(test, feature = "serde"))]
|
||||||
|
extern crate bincode;
|
||||||
|
#[cfg(all(test, feature = "serde"))]
|
||||||
|
extern crate serde_json;
|
||||||
|
#[cfg(all(test, feature = "serde"))]
|
||||||
|
extern crate serde_test;
|
||||||
|
#[cfg(all(test, feature = "unstable"))]
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -92,45 +100,37 @@ mod serde_utils;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod blockdata;
|
pub mod blockdata;
|
||||||
pub mod util;
|
|
||||||
pub mod consensus;
|
pub mod consensus;
|
||||||
pub mod hash_types;
|
pub mod hash_types;
|
||||||
pub mod policy;
|
pub mod policy;
|
||||||
|
pub mod util;
|
||||||
pub use crate::hash_types::*;
|
|
||||||
pub use crate::blockdata::block::Block;
|
|
||||||
pub use crate::blockdata::block::BlockHeader;
|
|
||||||
pub use crate::blockdata::script::Script;
|
|
||||||
pub use crate::blockdata::transaction::Transaction;
|
|
||||||
pub use crate::blockdata::transaction::TxIn;
|
|
||||||
pub use crate::blockdata::transaction::Sequence;
|
|
||||||
pub use crate::blockdata::transaction::TxOut;
|
|
||||||
pub use crate::blockdata::transaction::OutPoint;
|
|
||||||
pub use crate::blockdata::transaction::EcdsaSighashType;
|
|
||||||
pub use crate::blockdata::witness::Witness;
|
|
||||||
pub use crate::consensus::encode::VarInt;
|
|
||||||
pub use crate::network::constants::Network;
|
|
||||||
pub use crate::util::Error;
|
|
||||||
pub use crate::util::address::Address;
|
|
||||||
pub use crate::util::address::AddressType;
|
|
||||||
pub use crate::util::amount::Amount;
|
|
||||||
pub use crate::util::amount::Denomination;
|
|
||||||
pub use crate::util::amount::SignedAmount;
|
|
||||||
pub use crate::util::merkleblock::MerkleBlock;
|
|
||||||
pub use crate::util::sighash::SchnorrSighashType;
|
|
||||||
|
|
||||||
pub use crate::util::ecdsa::{self, EcdsaSig, EcdsaSigError};
|
|
||||||
pub use crate::util::schnorr::{self, SchnorrSig, SchnorrSigError};
|
|
||||||
pub use crate::util::key::{PrivateKey, PublicKey, XOnlyPublicKey, KeyPair};
|
|
||||||
pub use crate::util::psbt;
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use crate::blockdata::transaction::SigHashType;
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
use core2::io;
|
use core2::io;
|
||||||
|
|
||||||
|
pub use crate::blockdata::block::{Block, BlockHeader};
|
||||||
|
pub use crate::blockdata::script::Script;
|
||||||
|
#[allow(deprecated)]
|
||||||
|
pub use crate::blockdata::transaction::SigHashType;
|
||||||
|
pub use crate::blockdata::transaction::{
|
||||||
|
EcdsaSighashType, OutPoint, Sequence, Transaction, TxIn, TxOut,
|
||||||
|
};
|
||||||
|
pub use crate::blockdata::witness::Witness;
|
||||||
|
pub use crate::consensus::encode::VarInt;
|
||||||
|
pub use crate::hash_types::*;
|
||||||
|
pub use crate::network::constants::Network;
|
||||||
|
pub use crate::util::address::{Address, AddressType};
|
||||||
|
pub use crate::util::amount::{Amount, Denomination, SignedAmount};
|
||||||
|
pub use crate::util::ecdsa::{self, EcdsaSig, EcdsaSigError};
|
||||||
|
pub use crate::util::key::{KeyPair, PrivateKey, PublicKey, XOnlyPublicKey};
|
||||||
|
pub use crate::util::merkleblock::MerkleBlock;
|
||||||
|
pub use crate::util::schnorr::{self, SchnorrSig, SchnorrSigError};
|
||||||
|
pub use crate::util::sighash::SchnorrSighashType;
|
||||||
|
pub use crate::util::{psbt, Error};
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
mod io_extras {
|
mod io_extras {
|
||||||
/// A writer which will move data into the void.
|
/// A writer which will move data into the void.
|
||||||
|
@ -139,23 +139,18 @@ mod io_extras {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an instance of a writer which will successfully consume all data.
|
/// Creates an instance of a writer which will successfully consume all data.
|
||||||
pub const fn sink() -> Sink {
|
pub const fn sink() -> Sink { Sink { _priv: () } }
|
||||||
Sink { _priv: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core2::io::Write for Sink {
|
impl core2::io::Write for Sink {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> { Ok(buf.len()) }
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> core2::io::Result<()> {
|
fn flush(&mut self) -> core2::io::Result<()> { Ok(()) }
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
mod prelude {
|
mod prelude {
|
||||||
#[cfg(all(not(feature = "std"), not(test)))]
|
#[cfg(all(not(feature = "std"), not(test)))]
|
||||||
pub use alloc::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Cow, ToOwned}, slice, rc, sync};
|
pub use alloc::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Cow, ToOwned}, slice, rc, sync};
|
||||||
|
@ -182,32 +177,26 @@ mod prelude {
|
||||||
pub use std::collections::HashSet;
|
pub use std::collections::HashSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(bench)] use bench::EmptyWrite;
|
#[cfg(bench)]
|
||||||
|
use bench::EmptyWrite;
|
||||||
|
|
||||||
#[cfg(bench)]
|
#[cfg(bench)]
|
||||||
mod bench {
|
mod bench {
|
||||||
use core::fmt::Arguments;
|
use core::fmt::Arguments;
|
||||||
|
|
||||||
use crate::io::{IoSlice, Result, Write};
|
use crate::io::{IoSlice, Result, Write};
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
|
#[derive(Default, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct EmptyWrite;
|
pub struct EmptyWrite;
|
||||||
|
|
||||||
impl Write for EmptyWrite {
|
impl Write for EmptyWrite {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
fn write_vectored(&mut self, bufs: &[IoSlice]) -> Result<usize> {
|
fn write_vectored(&mut self, bufs: &[IoSlice]) -> Result<usize> {
|
||||||
Ok(bufs.iter().map(|s| s.len()).sum())
|
Ok(bufs.iter().map(|s| s.len()).sum())
|
||||||
}
|
}
|
||||||
fn flush(&mut self) -> Result<()> {
|
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_all(&mut self, _: &[u8]) -> Result<()> {
|
fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
|
||||||
Ok(())
|
fn write_fmt(&mut self, _: Arguments) -> Result<()> { Ok(()) }
|
||||||
}
|
|
||||||
fn write_fmt(&mut self, _: Arguments) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
//! These values were taken from bitcoind v0.21.1 (194b9b8792d9b0798fdb570b79fa51f1d1f5ebaf).
|
//! These values were taken from bitcoind v0.21.1 (194b9b8792d9b0798fdb570b79fa51f1d1f5ebaf).
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use super::blockdata::constants::{MAX_BLOCK_SIGOPS_COST, WITNESS_SCALE_FACTOR};
|
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
|
|
||||||
|
use super::blockdata::constants::{MAX_BLOCK_SIGOPS_COST, WITNESS_SCALE_FACTOR};
|
||||||
|
|
||||||
/// Maximum weight of a transaction for it to be relayed by most nodes on the network
|
/// Maximum weight of a transaction for it to be relayed by most nodes on the network
|
||||||
pub const MAX_STANDARD_TX_WEIGHT: u32 = 400_000;
|
pub const MAX_STANDARD_TX_WEIGHT: u32 = 400_000;
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,11 @@ pub mod btreemap_byte_values {
|
||||||
|
|
||||||
// NOTE: This module can be exactly copied to use with HashMap.
|
// NOTE: This module can be exactly copied to use with HashMap.
|
||||||
|
|
||||||
use crate::prelude::*;
|
|
||||||
use crate::hashes::hex::{FromHex, ToHex};
|
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
|
use crate::hashes::hex::{FromHex, ToHex};
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn serialize<S, T>(v: &BTreeMap<T, Vec<u8>>, s: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S, T>(v: &BTreeMap<T, Vec<u8>>, s: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
|
@ -52,9 +53,10 @@ pub mod btreemap_byte_values {
|
||||||
write!(f, "a map with hexadecimal values")
|
write!(f, "a map with hexadecimal values")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<A: serde::de::MapAccess<'de>>(self, mut a: A)
|
fn visit_map<A: serde::de::MapAccess<'de>>(
|
||||||
-> Result<Self::Value, A::Error>
|
self,
|
||||||
{
|
mut a: A,
|
||||||
|
) -> Result<Self::Value, A::Error> {
|
||||||
let mut ret = BTreeMap::new();
|
let mut ret = BTreeMap::new();
|
||||||
while let Some((key, value)) = a.next_entry()? {
|
while let Some((key, value)) = a.next_entry()? {
|
||||||
ret.insert(key, FromHex::from_hex(value).map_err(serde::de::Error::custom)?);
|
ret.insert(key, FromHex::from_hex(value).map_err(serde::de::Error::custom)?);
|
||||||
|
@ -79,9 +81,10 @@ pub mod btreemap_as_seq {
|
||||||
|
|
||||||
// NOTE: This module can be exactly copied to use with HashMap.
|
// NOTE: This module can be exactly copied to use with HashMap.
|
||||||
|
|
||||||
use crate::prelude::*;
|
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn serialize<S, T, U>(v: &BTreeMap<T, U>, s: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S, T, U>(v: &BTreeMap<T, U>, s: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
|
@ -122,9 +125,10 @@ pub mod btreemap_as_seq {
|
||||||
write!(f, "a sequence of pairs")
|
write!(f, "a sequence of pairs")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut a: A)
|
fn visit_seq<A: serde::de::SeqAccess<'de>>(
|
||||||
-> Result<Self::Value, A::Error>
|
self,
|
||||||
{
|
mut a: A,
|
||||||
|
) -> Result<Self::Value, A::Error> {
|
||||||
let mut ret = BTreeMap::new();
|
let mut ret = BTreeMap::new();
|
||||||
while let Some((key, value)) = a.next_element()? {
|
while let Some((key, value)) = a.next_element()? {
|
||||||
ret.insert(key, value);
|
ret.insert(key, value);
|
||||||
|
@ -149,16 +153,16 @@ pub mod btreemap_as_seq_byte_values {
|
||||||
|
|
||||||
// NOTE: This module can be exactly copied to use with HashMap.
|
// NOTE: This module can be exactly copied to use with HashMap.
|
||||||
|
|
||||||
use crate::prelude::*;
|
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// A custom key-value pair type that serialized the bytes as hex.
|
/// A custom key-value pair type that serialized the bytes as hex.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(crate = "actual_serde")]
|
#[serde(crate = "actual_serde")]
|
||||||
struct OwnedPair<T>(
|
struct OwnedPair<T>(
|
||||||
T,
|
T,
|
||||||
#[serde(deserialize_with = "crate::serde_utils::hex_bytes::deserialize")]
|
#[serde(deserialize_with = "crate::serde_utils::hex_bytes::deserialize")] Vec<u8>,
|
||||||
Vec<u8>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A custom key-value pair type that serialized the bytes as hex.
|
/// A custom key-value pair type that serialized the bytes as hex.
|
||||||
|
@ -166,8 +170,7 @@ pub mod btreemap_as_seq_byte_values {
|
||||||
#[serde(crate = "actual_serde")]
|
#[serde(crate = "actual_serde")]
|
||||||
struct BorrowedPair<'a, T: 'static>(
|
struct BorrowedPair<'a, T: 'static>(
|
||||||
&'a T,
|
&'a T,
|
||||||
#[serde(serialize_with = "crate::serde_utils::hex_bytes::serialize")]
|
#[serde(serialize_with = "crate::serde_utils::hex_bytes::serialize")] &'a [u8],
|
||||||
&'a [u8],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn serialize<S, T>(v: &BTreeMap<T, Vec<u8>>, s: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S, T>(v: &BTreeMap<T, Vec<u8>>, s: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -207,9 +210,10 @@ pub mod btreemap_as_seq_byte_values {
|
||||||
write!(f, "a sequence of pairs")
|
write!(f, "a sequence of pairs")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut a: A)
|
fn visit_seq<A: serde::de::SeqAccess<'de>>(
|
||||||
-> Result<Self::Value, A::Error>
|
self,
|
||||||
{
|
mut a: A,
|
||||||
|
) -> Result<Self::Value, A::Error> {
|
||||||
let mut ret = BTreeMap::new();
|
let mut ret = BTreeMap::new();
|
||||||
while let Option::Some(OwnedPair(key, value)) = a.next_element()? {
|
while let Option::Some(OwnedPair(key, value)) = a.next_element()? {
|
||||||
ret.insert(key, value);
|
ret.insert(key, value);
|
||||||
|
@ -236,7 +240,8 @@ pub mod hex_bytes {
|
||||||
|
|
||||||
pub fn serialize<T, S>(bytes: &T, s: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<T, S>(bytes: &T, s: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
T: serde::Serialize + AsRef<[u8]>, S: serde::Serializer
|
T: serde::Serialize + AsRef<[u8]>,
|
||||||
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
// Don't do anything special when not human readable.
|
// Don't do anything special when not human readable.
|
||||||
if !s.is_human_readable() {
|
if !s.is_human_readable() {
|
||||||
|
@ -248,7 +253,8 @@ pub mod hex_bytes {
|
||||||
|
|
||||||
pub fn deserialize<'de, D, B>(d: D) -> Result<B, D::Error>
|
pub fn deserialize<'de, D, B>(d: D) -> Result<B, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>, B: serde::Deserialize<'de> + FromHex,
|
D: serde::Deserializer<'de>,
|
||||||
|
B: serde::Deserialize<'de> + FromHex,
|
||||||
{
|
{
|
||||||
struct Visitor<B>(core::marker::PhantomData<B>);
|
struct Visitor<B>(core::marker::PhantomData<B>);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue