Merge rust-bitcoin/rust-bitcoin#2473: Upgrade to `hex v0.2.0`
f337dec2b1
hashes: Remove unnecessary feature guard from test (Tobin C. Harding)0cea90d505
Test hashes honour Formatter::precision (Tobin C. Harding)4bfb466bb9
Upgrade hex dependency (Tobin C. Harding)f0558e8eb9
Use fmt_hex_exact (Tobin C. Harding)6820f51408
hashes: Add fmt roundtrip tests (Tobin C. Harding)e302e30e7c
Import with super::* in unit test (Tobin C. Harding) Pull request description: Upgrade to use the newly released `hex` code. - Patch 1: Does trivial preparatory cleanup - Patch 2: Adds some unit tests to check we roundtrip hashes correctly (added because in the test PR I had the `Midstate` iml wrong and it was not being caught). - Patch 3: Uses macro in place of `forward_hex` and `backward_hex` - needs concept review, I hacked this without understanding why the functions existed in the first place. - Patch 4: Does the upgrade, I've attempted to make minimal changes, so there is room for a bunch of cleanups if/when this merges. - Patch 5: Adds a unit test to verify that we can close #2494 - Patch 6: Removes unnecessary feature gate from unit test. ACKs for top commit: Kixunil: ACKf337dec2b1
apoelstra: ACKf337dec2b1
Tree-SHA512: 7913d1b3079cf5ba1b0e70f5c33e091c5ef1258026c8f27bbe8a050100bbc7622b6555d560b15be3b3d90d47ce873f137a73cf2d772108d2915fb30ed129bded
This commit is contained in:
commit
a124ff41c4
|
@ -8,6 +8,12 @@ version = "1.0.57"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "base58check"
|
||||
version = "0.1.0"
|
||||
|
@ -159,9 +165,12 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
|||
|
||||
[[package]]
|
||||
name = "hex-conservative"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2"
|
||||
checksum = "e1aa273bf451e37ed35ced41c71a5e2a4e29064afb104158f2514bcd71c2c986"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex_lit"
|
||||
|
|
|
@ -8,6 +8,12 @@ version = "1.0.71"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "base58check"
|
||||
version = "0.1.0"
|
||||
|
@ -158,9 +164,12 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
|||
|
||||
[[package]]
|
||||
name = "hex-conservative"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2"
|
||||
checksum = "e1aa273bf451e37ed35ced41c71a5e2a4e29064afb104158f2514bcd71c2c986"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex_lit"
|
||||
|
|
|
@ -25,4 +25,4 @@ hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = fa
|
|||
internals = { package = "bitcoin-internals", version = "0.2.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }
|
||||
hex = { package = "hex-conservative", version = "0.2.0", default-features = false, features = ["alloc"] }
|
||||
|
|
|
@ -31,7 +31,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||
base58 = { package = "base58check", version = "0.1.0", default-features = false }
|
||||
bech32 = { version = "0.11.0", default-features = false, features = ["alloc"] }
|
||||
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false, features = ["alloc", "io"] }
|
||||
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }
|
||||
hex = { package = "hex-conservative", version = "0.2.0", default-features = false, features = ["alloc"] }
|
||||
hex_lit = "0.1.1"
|
||||
internals = { package = "bitcoin-internals", version = "0.2.0" }
|
||||
io = { package = "bitcoin-io", version = "0.1.1", default-features = false, features = ["alloc"] }
|
||||
|
|
|
@ -1960,6 +1960,10 @@ mod tests {
|
|||
format!("{:x}", tx.compute_txid()),
|
||||
"9652aa62b0e748caeec40c4cb7bc17c6792435cc3dfe447dd1ca24f912a1c6ec"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{:.10x}", tx.compute_txid()),
|
||||
"9652aa62b0"
|
||||
);
|
||||
assert_eq!(tx.weight(), Weight::from_wu(2718));
|
||||
|
||||
// non-segwit tx from my mempool
|
||||
|
|
|
@ -506,18 +506,19 @@ impl<'de> serde::Deserialize<'de> for Witness {
|
|||
|
||||
while let Some(elem) = a.next_element::<String>()? {
|
||||
let vec = Vec::<u8>::from_hex(&elem).map_err(|e| match e {
|
||||
InvalidChar(b) => match core::char::from_u32(b.into()) {
|
||||
InvalidChar(ref e) => match core::char::from_u32(e.invalid_char(
|
||||
).into()) {
|
||||
Some(c) => de::Error::invalid_value(
|
||||
Unexpected::Char(c),
|
||||
&"a valid hex character",
|
||||
),
|
||||
None => de::Error::invalid_value(
|
||||
Unexpected::Unsigned(b.into()),
|
||||
Unexpected::Unsigned(e.invalid_char().into()),
|
||||
&"a valid hex character",
|
||||
),
|
||||
},
|
||||
OddLengthString(len) =>
|
||||
de::Error::invalid_length(len, &"an even length string"),
|
||||
OddLengthString(ref e) =>
|
||||
de::Error::invalid_length(e.length(), &"an even length string"),
|
||||
})?;
|
||||
ret.push(vec);
|
||||
}
|
||||
|
|
|
@ -71,11 +71,11 @@ pub mod hex {
|
|||
|
||||
/// Hex byte encoder.
|
||||
// We wrap `BufEncoder` to not leak internal representation.
|
||||
pub struct Encoder<C: Case>(BufEncoder<[u8; HEX_BUF_SIZE]>, PhantomData<C>);
|
||||
pub struct Encoder<C: Case>(BufEncoder<{ HEX_BUF_SIZE }>, PhantomData<C>);
|
||||
|
||||
impl<C: Case> From<super::Hex<C>> for Encoder<C> {
|
||||
fn from(_: super::Hex<C>) -> Self {
|
||||
Encoder(BufEncoder::new([0; HEX_BUF_SIZE]), Default::default())
|
||||
Encoder(BufEncoder::new(), Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,15 +100,15 @@ pub mod hex {
|
|||
// Newtypes to hide internal details.
|
||||
|
||||
/// Error returned when a hex string decoder can't be created.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DecodeInitError(hex::HexToBytesError);
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DecodeInitError(hex::OddLengthStringError);
|
||||
|
||||
/// Error returned when a hex string contains invalid characters.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DecodeError(hex::HexToBytesError);
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DecodeError(hex::InvalidCharError);
|
||||
|
||||
/// Hex decoder state.
|
||||
pub struct Decoder<'a>(hex::HexToBytesIter<'a>);
|
||||
pub struct Decoder<'a>(hex::HexSliceToBytesIter<'a>);
|
||||
|
||||
impl<'a> Decoder<'a> {
|
||||
fn new(s: &'a str) -> Result<Self, DecodeInitError> {
|
||||
|
@ -137,29 +137,19 @@ pub mod hex {
|
|||
|
||||
impl super::IntoDeError for DecodeInitError {
|
||||
fn into_de_error<E: serde::de::Error>(self) -> E {
|
||||
use hex::HexToBytesError;
|
||||
|
||||
match self.0 {
|
||||
HexToBytesError::OddLengthString(len) =>
|
||||
E::invalid_length(len, &"an even number of ASCII-encoded hex digits"),
|
||||
error => panic!("unexpected error: {:?}", error),
|
||||
}
|
||||
E::invalid_length(self.0.length(), &"an even number of ASCII-encoded hex digits")
|
||||
}
|
||||
}
|
||||
|
||||
impl super::IntoDeError for DecodeError {
|
||||
fn into_de_error<E: serde::de::Error>(self) -> E {
|
||||
use hex::HexToBytesError;
|
||||
use serde::de::Unexpected;
|
||||
|
||||
const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit";
|
||||
|
||||
match self.0 {
|
||||
HexToBytesError::InvalidChar(c) if c.is_ascii() =>
|
||||
E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR),
|
||||
HexToBytesError::InvalidChar(c) =>
|
||||
E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR),
|
||||
error => panic!("unexpected error: {:?}", error),
|
||||
match self.0.invalid_char() {
|
||||
c if c.is_ascii() => E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR),
|
||||
c => E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use core::ops;
|
|||
use core::str::FromStr;
|
||||
|
||||
use hashes::{hash160, Hash};
|
||||
use hex::{FromHex, HexToArrayError, HexToBytesError};
|
||||
use hex::{FromHex, HexToArrayError};
|
||||
use internals::array_vec::ArrayVec;
|
||||
use internals::write_err;
|
||||
use io::{Read, Write};
|
||||
|
@ -233,22 +233,22 @@ impl fmt::Display for PublicKey {
|
|||
impl FromStr for PublicKey {
|
||||
type Err = ParsePublicKeyError;
|
||||
fn from_str(s: &str) -> Result<PublicKey, ParsePublicKeyError> {
|
||||
use HexToArrayError::*;
|
||||
|
||||
match s.len() {
|
||||
66 => {
|
||||
PublicKey::from_slice(&<[u8; 33]>::from_hex(s).map_err(|op| {
|
||||
match op {
|
||||
HexToArrayError::Conversion(HexToBytesError::InvalidChar(char)) => ParsePublicKeyError::InvalidChar(char),
|
||||
HexToArrayError::Conversion(HexToBytesError::OddLengthString(_)) | HexToArrayError::InvalidLength(_,_) => unreachable!("invalid length"),
|
||||
}
|
||||
})?).map_err(From::from)
|
||||
let bytes = <[u8; 33]>::from_hex(s).map_err(|e| match e {
|
||||
InvalidChar(e) => ParsePublicKeyError::InvalidChar(e.invalid_char()),
|
||||
InvalidLength(_) => unreachable!("length checked already")
|
||||
})?;
|
||||
Ok(PublicKey::from_slice(&bytes).expect("length checked already"))
|
||||
},
|
||||
130 => {
|
||||
PublicKey::from_slice(&<[u8; 65]>::from_hex(s).map_err(|op| {
|
||||
match op {
|
||||
HexToArrayError::Conversion(HexToBytesError::InvalidChar(char)) => ParsePublicKeyError::InvalidChar(char),
|
||||
HexToArrayError::Conversion(HexToBytesError::OddLengthString(_)) | HexToArrayError::InvalidLength(_,_) => unreachable!("invalid length"),
|
||||
}
|
||||
})?).map_err(From::from)
|
||||
let bytes = <[u8; 65]>::from_hex(s).map_err(|e| match e {
|
||||
InvalidChar(e) => ParsePublicKeyError::InvalidChar(e.invalid_char()),
|
||||
InvalidLength(_) => unreachable!("length checked already")
|
||||
})?;
|
||||
Ok(PublicKey::from_slice(&bytes).expect("length checked already"))
|
||||
}
|
||||
len => Err(ParsePublicKeyError::InvalidHexLength(len)),
|
||||
}
|
||||
|
|
|
@ -1035,7 +1035,7 @@ mod tests {
|
|||
|
||||
#[track_caller]
|
||||
pub fn hex_psbt(s: &str) -> Result<Psbt, crate::psbt::error::Error> {
|
||||
let r: Result<Vec<u8>, hex::HexToBytesError> = Vec::from_hex(s);
|
||||
let r = Vec::from_hex(s);
|
||||
match r {
|
||||
Err(_e) => panic!("unable to parse hex string {}", s),
|
||||
Ok(v) => Psbt::deserialize(&v),
|
||||
|
|
|
@ -28,10 +28,7 @@ impl fmt::Debug for SerializedSignature {
|
|||
|
||||
impl fmt::Display for SerializedSignature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut buf = [0u8; MAX_LEN * 2];
|
||||
let mut encoder = hex::buf_encoder::BufEncoder::new(&mut buf);
|
||||
encoder.put_bytes(self, hex::Case::Lower);
|
||||
f.pad_integral(true, "0x", encoder.as_str())
|
||||
hex::fmt_hex_exact!(f, MAX_LEN, self, hex::Case::Lower)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ all-features = true
|
|||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
|
||||
hex = { package = "hex-conservative", version = "0.2.0", default-features = false }
|
||||
|
||||
bitcoin-io = { version = "0.1.1", default-features = false, optional = true }
|
||||
schemars = { version = "0.8.3", default-features = false, optional = true }
|
||||
|
|
|
@ -71,22 +71,6 @@ pub(crate) use arr_newtype_fmt_impl;
|
|||
macro_rules! hash_trait_impls {
|
||||
($bits:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
||||
impl<$($gen: $gent),*> Hash<$($gen),*> {
|
||||
/// Displays hex forwards, regardless of how this type would display it naturally.
|
||||
///
|
||||
/// This is mainly intended as an internal method and you shouldn't need it unless
|
||||
/// you're doing something special.
|
||||
pub fn forward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
|
||||
$crate::hex::DisplayHex::as_hex(&self.0)
|
||||
}
|
||||
|
||||
/// Displays hex backwards, regardless of how this type would display it naturally.
|
||||
///
|
||||
/// This is mainly intended as an internal method and you shouldn't need it unless
|
||||
/// you're doing something special.
|
||||
pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
|
||||
$crate::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev())
|
||||
}
|
||||
|
||||
/// Zero cost conversion between a fixed length byte array shared reference and
|
||||
/// a shared reference to this Hash type.
|
||||
pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self {
|
||||
|
@ -105,15 +89,13 @@ macro_rules! hash_trait_impls {
|
|||
impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> {
|
||||
type Err = $crate::hex::HexToArrayError;
|
||||
fn from_str(s: &str) -> $crate::_export::_core::result::Result<Self, Self::Err> {
|
||||
use $crate::hex::{FromHex, HexToBytesIter};
|
||||
use $crate::Hash;
|
||||
use $crate::{Hash, hex::{FromHex}};
|
||||
|
||||
let inner: [u8; $bits / 8] = if $reverse {
|
||||
FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
|
||||
} else {
|
||||
FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
|
||||
};
|
||||
Ok(Self::from_byte_array(inner))
|
||||
let mut bytes = <[u8; $bits / 8]>::from_hex(s)?;
|
||||
if $reverse {
|
||||
bytes.reverse();
|
||||
}
|
||||
Ok(Self::from_byte_array(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -273,4 +273,12 @@ mod tests {
|
|||
let h2: TestNewtype = h.to_string().parse().unwrap();
|
||||
assert_eq!(h2.to_raw_hash(), h);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn newtype_fmt_roundtrip() {
|
||||
let orig = TestNewtype::hash(&[]);
|
||||
let hex = format!("{}", orig);
|
||||
let rinsed = hex.parse::<TestNewtype>().expect("failed to parse hex");
|
||||
assert_eq!(rinsed, orig)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,15 +176,13 @@ impl Midstate {
|
|||
}
|
||||
|
||||
impl hex::FromHex for Midstate {
|
||||
type Err = hex::HexToArrayError;
|
||||
fn from_byte_iter<I>(iter: I) -> Result<Self, Self::Err>
|
||||
where
|
||||
I: Iterator<Item = Result<u8, hex::HexToBytesError>>
|
||||
+ ExactSizeIterator
|
||||
+ DoubleEndedIterator,
|
||||
{
|
||||
type Error = hex::HexToArrayError;
|
||||
|
||||
fn from_hex(s: &str) -> Result<Self, Self::Error> {
|
||||
// DISPLAY_BACKWARD is true
|
||||
Ok(Midstate::from_byte_array(hex::FromHex::from_byte_iter(iter.rev())?))
|
||||
let mut bytes = <[u8; 32]>::from_hex(s)?;
|
||||
bytes.reverse();
|
||||
Ok(Midstate(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,7 +815,8 @@ impl HashEngine {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{sha256, Hash, HashEngine};
|
||||
use crate::{sha256, Hash as _, HashEngine};
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
|
@ -882,6 +881,14 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_roundtrips() {
|
||||
let hash = sha256::Hash::hash(b"some arbitrary bytes");
|
||||
let hex = format!("{}", hash);
|
||||
let rinsed = hex.parse::<sha256::Hash>().expect("failed to parse hex");
|
||||
assert_eq!(rinsed, hash)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn midstate() {
|
||||
|
@ -964,14 +971,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn const_hash() {
|
||||
assert_eq!(super::Hash::hash(&[]), super::Hash::const_hash(&[]));
|
||||
assert_eq!(Hash::hash(&[]), Hash::const_hash(&[]));
|
||||
|
||||
let mut bytes = Vec::new();
|
||||
for i in 0..256 {
|
||||
bytes.push(i as u8);
|
||||
assert_eq!(
|
||||
super::Hash::hash(&bytes),
|
||||
super::Hash::const_hash(&bytes),
|
||||
Hash::hash(&bytes),
|
||||
Hash::const_hash(&bytes),
|
||||
"hashes don't match for length {}",
|
||||
i + 1
|
||||
);
|
||||
|
@ -980,8 +987,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn const_midstate() {
|
||||
use super::Midstate;
|
||||
|
||||
assert_eq!(
|
||||
Midstate::hash_tag(b"TapLeaf"),
|
||||
Midstate([
|
||||
|
@ -991,6 +996,14 @@ mod tests {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn midstate_fmt_roundtrip() {
|
||||
let midstate = Midstate::hash_tag(b"ArbitraryTag");
|
||||
let hex = format!("{}", midstate);
|
||||
let rinsed = hex.parse::<Midstate>().expect("failed to parse hex");
|
||||
assert_eq!(rinsed, midstate)
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn sha256_serde() {
|
||||
|
|
|
@ -30,10 +30,12 @@ fn from_engine(e: sha256::HashEngine) -> Hash {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{sha256d, Hash as _};
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn test() {
|
||||
use crate::{sha256, sha256d, Hash, HashEngine};
|
||||
use crate::{sha256, HashEngine};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Test {
|
||||
|
@ -81,13 +83,19 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_roundtrips() {
|
||||
let hash = sha256d::Hash::hash(b"some arbitrary bytes");
|
||||
let hex = format!("{}", hash);
|
||||
let rinsed = hex.parse::<sha256d::Hash>().expect("failed to parse hex");
|
||||
assert_eq!(rinsed, hash)
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn sha256_serde() {
|
||||
use serde_test::{assert_tokens, Configure, Token};
|
||||
|
||||
use crate::{sha256d, Hash};
|
||||
|
||||
#[rustfmt::skip]
|
||||
static HASH_BYTES: [u8; 32] = [
|
||||
0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7,
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
#[macro_export]
|
||||
/// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`.
|
||||
macro_rules! hex_fmt_impl(
|
||||
($reverse:expr, $ty:ident) => (
|
||||
$crate::hex_fmt_impl!($reverse, $ty, );
|
||||
($reverse:expr, $len:expr, $ty:ident) => (
|
||||
$crate::hex_fmt_impl!($reverse, $len, $ty, );
|
||||
);
|
||||
($reverse:expr, $ty:ident, $($gen:ident: $gent:ident),*) => (
|
||||
($reverse:expr, $len:expr, $ty:ident, $($gen:ident: $gent:ident),*) => (
|
||||
impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
|
||||
if $reverse {
|
||||
$crate::_export::_core::fmt::LowerHex::fmt(&self.0.backward_hex(), f)
|
||||
$crate::hex::fmt_hex_exact!(f, $len, <Self as $crate::Hash>::as_byte_array(&self).iter().rev(), $crate::hex::Case::Lower)
|
||||
} else {
|
||||
$crate::_export::_core::fmt::LowerHex::fmt(&self.0.forward_hex(), f)
|
||||
$crate::hex::fmt_hex_exact!(f, $len, <Self as $crate::Hash>::as_byte_array(&self), $crate::hex::Case::Lower)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ macro_rules! hex_fmt_impl(
|
|||
#[inline]
|
||||
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
|
||||
if $reverse {
|
||||
$crate::_export::_core::fmt::UpperHex::fmt(&self.0.backward_hex(), f)
|
||||
$crate::hex::fmt_hex_exact!(f, $len, <Self as $crate::Hash>::as_byte_array(&self).iter().rev(), $crate::hex::Case::Upper)
|
||||
} else {
|
||||
$crate::_export::_core::fmt::UpperHex::fmt(&self.0.forward_hex(), f)
|
||||
$crate::hex::fmt_hex_exact!(f, $len, <Self as $crate::Hash>::as_byte_array(&self), $crate::hex::Case::Upper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ macro_rules! hash_newtype {
|
|||
$({ $($type_attrs)* })*
|
||||
}
|
||||
|
||||
$crate::hex_fmt_impl!(<$newtype as $crate::Hash>::DISPLAY_BACKWARD, $newtype);
|
||||
$crate::hex_fmt_impl!(<$newtype as $crate::Hash>::DISPLAY_BACKWARD, <$newtype as $crate::Hash>::LEN, $newtype);
|
||||
$crate::serde_impl!($newtype, <$newtype as $crate::Hash>::LEN);
|
||||
$crate::borrow_slice_impl!($newtype);
|
||||
|
||||
|
@ -270,15 +270,13 @@ macro_rules! hash_newtype {
|
|||
impl $crate::_export::_core::str::FromStr for $newtype {
|
||||
type Err = $crate::hex::HexToArrayError;
|
||||
fn from_str(s: &str) -> $crate::_export::_core::result::Result<$newtype, Self::Err> {
|
||||
use $crate::hex::{FromHex, HexToBytesIter};
|
||||
use $crate::Hash;
|
||||
use $crate::{Hash, hex::FromHex};
|
||||
|
||||
let inner: <$hash as Hash>::Bytes = if <Self as $crate::Hash>::DISPLAY_BACKWARD {
|
||||
FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
|
||||
} else {
|
||||
FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
|
||||
let mut bytes = <[u8; <Self as $crate::Hash>::LEN]>::from_hex(s)?;
|
||||
if <Self as $crate::Hash>::DISPLAY_BACKWARD {
|
||||
bytes.reverse();
|
||||
};
|
||||
Ok($newtype(<$hash>::from_byte_array(inner)))
|
||||
Ok($newtype(<$hash>::from_byte_array(bytes)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue