zebra_chain/transaction/
auth_digest.rs1use std::{array::TryFromSliceError, fmt};
4
5use hex::{FromHex, ToHex};
6
7use crate::serialization::{
8 BytesInDisplayOrder, ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize,
9 ZcashSerialize,
10};
11
12#[cfg(any(test, feature = "proptest-impl"))]
13use proptest_derive::Arbitrary;
14
15#[derive(Copy, Clone, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize)]
22#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
23pub struct AuthDigest(pub [u8; 32]);
24
25impl BytesInDisplayOrder<true> for AuthDigest {
26 fn bytes_in_serialized_order(&self) -> [u8; 32] {
27 self.0
28 }
29
30 fn from_bytes_in_serialized_order(bytes: [u8; 32]) -> Self {
31 AuthDigest(bytes)
32 }
33}
34
35impl From<[u8; 32]> for AuthDigest {
38 fn from(bytes: [u8; 32]) -> Self {
39 Self(bytes)
40 }
41}
42
43impl TryFrom<&[u8]> for AuthDigest {
44 type Error = TryFromSliceError;
45
46 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
47 Ok(AuthDigest(bytes.try_into()?))
48 }
49}
50
51impl From<AuthDigest> for [u8; 32] {
52 fn from(auth_digest: AuthDigest) -> Self {
53 auth_digest.0
54 }
55}
56
57impl From<&AuthDigest> for [u8; 32] {
58 fn from(auth_digest: &AuthDigest) -> Self {
59 (*auth_digest).into()
60 }
61}
62
63impl ToHex for &AuthDigest {
64 fn encode_hex<T: FromIterator<char>>(&self) -> T {
65 self.bytes_in_display_order().encode_hex()
66 }
67
68 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
69 self.bytes_in_display_order().encode_hex_upper()
70 }
71}
72
73impl ToHex for AuthDigest {
74 fn encode_hex<T: FromIterator<char>>(&self) -> T {
75 (&self).encode_hex()
76 }
77
78 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
79 (&self).encode_hex_upper()
80 }
81}
82
83impl FromHex for AuthDigest {
84 type Error = <[u8; 32] as FromHex>::Error;
85
86 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
87 let mut hash = <[u8; 32]>::from_hex(hex)?;
88 hash.reverse();
89
90 Ok(hash.into())
91 }
92}
93
94impl fmt::Display for AuthDigest {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 f.write_str(&self.encode_hex::<String>())
97 }
98}
99
100impl fmt::Debug for AuthDigest {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 f.debug_tuple("AuthDigest")
103 .field(&self.encode_hex::<String>())
104 .finish()
105 }
106}
107
108impl std::str::FromStr for AuthDigest {
109 type Err = SerializationError;
110
111 fn from_str(s: &str) -> Result<Self, Self::Err> {
112 let mut bytes = [0; 32];
113 if hex::decode_to_slice(s, &mut bytes[..]).is_err() {
114 Err(SerializationError::Parse("hex decoding error"))
115 } else {
116 bytes.reverse();
117 Ok(AuthDigest(bytes))
118 }
119 }
120}
121
122impl ZcashSerialize for AuthDigest {
123 fn zcash_serialize<W: std::io::Write>(&self, mut writer: W) -> Result<(), std::io::Error> {
124 writer.write_32_bytes(&self.into())
125 }
126}
127
128impl ZcashDeserialize for AuthDigest {
129 fn zcash_deserialize<R: std::io::Read>(mut reader: R) -> Result<Self, SerializationError> {
130 Ok(reader.read_32_bytes()?.into())
131 }
132}