scsys_crypto/hash/
h256.rs1#[cfg(feature = "blake3")]
7mod impl_blake3;
8mod impl_convert;
9mod impl_ops;
10
11use crate::utils::digest_to_hash;
12
13pub type H256Array = [u8; 32];
15
16#[cfg_attr(
18 feature = "serde",
19 derive(serde::Deserialize, serde::Serialize),
20 serde(default, transparent)
21)]
22#[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
23#[repr(transparent)]
24pub struct H256(pub H256Array);
25
26impl H256 {
27 pub fn new(raw: H256Array) -> Self {
29 Self(raw)
30 }
31 pub fn from_digest<D>(digest: D) -> Self
33 where
34 D: AsRef<[u8]>,
35 {
36 let hash = digest_to_hash::<32>(digest);
37 Self::new(hash)
38 }
39 #[cfg(feature = "blake3")]
41 pub fn b3(data: impl AsRef<[u8]>) -> Self {
42 let hash = blake3::hash(data.as_ref());
43 H256(digest_to_hash::<32>(hash.as_bytes()))
44 }
45 #[cfg(feature = "rand")]
47 pub fn random() -> Self {
48 let data = rand::random::<H256Array>();
49 let mut raw_bytes = [0; 32];
50 raw_bytes.copy_from_slice(&data);
51 (&raw_bytes).into()
52 }
53 pub const fn get(&self) -> &H256Array {
55 &self.0
56 }
57 pub fn get_mut(&mut self) -> &mut H256Array {
59 &mut self.0
60 }
61 pub fn set(&mut self, value: H256Array) -> &mut Self {
63 self.0 = value;
64 self
65 }
66 pub fn replace(&mut self, value: &H256Array) -> H256Array {
68 core::mem::replace(&mut self.0, *value)
69 }
70 pub fn swap(&mut self, other: &mut Self) {
72 core::mem::swap(&mut self.0, &mut other.0)
73 }
74 pub const fn as_slice(&self) -> &[u8] {
76 &self.0
77 }
78 pub fn as_slice_mut(&mut self) -> &mut [u8] {
80 &mut self.0
81 }
82 pub fn copy_from_slice(&mut self, value: &[u8]) -> &mut Self {
84 self.0.copy_from_slice(value);
85 self
86 }
87 #[cfg(feature = "alloc")]
89 #[inline]
90 pub fn to_vec(&self) -> alloc::vec::Vec<u8> {
91 self.get().to_vec()
92 }
93 #[inline]
96 pub fn concat<Rhs>(&self, other: Rhs) -> Self
97 where
98 Self: crate::Concat<Rhs, Output = Self>,
99 {
100 crate::Concat::concat(self, other)
101 }
102}
103
104impl core::ops::Deref for H256 {
105 type Target = H256Array;
106
107 fn deref(&self) -> &Self::Target {
108 &self.0
109 }
110}
111
112impl core::ops::DerefMut for H256 {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.0
115 }
116}
117
118impl AsMut<[u8]> for H256 {
119 fn as_mut(&mut self) -> &mut [u8] {
120 &mut self.0
121 }
122}
123
124impl AsRef<[u8]> for H256 {
125 fn as_ref(&self) -> &[u8] {
126 &self.0
127 }
128}
129
130impl AsMut<[u8; 32]> for H256 {
131 fn as_mut(&mut self) -> &mut [u8; 32] {
132 &mut self.0
133 }
134}
135
136impl AsRef<[u8; 32]> for H256 {
137 fn as_ref(&self) -> &[u8; 32] {
138 &self.0
139 }
140}
141
142impl Ord for H256 {
143 fn cmp(&self, other: &H256) -> core::cmp::Ordering {
144 let self_higher = u128::from_be_bytes(self[0..16].try_into().unwrap());
145 let self_lower = u128::from_be_bytes(self[16..32].try_into().unwrap());
146 let other_higher = u128::from_be_bytes(other[0..16].try_into().unwrap());
147 let other_lower = u128::from_be_bytes(other[16..32].try_into().unwrap());
148 let higher = self_higher.cmp(&other_higher);
149 match higher {
150 core::cmp::Ordering::Equal => self_lower.cmp(&other_lower),
151 _ => higher,
152 }
153 }
154}
155
156impl PartialOrd for H256 {
157 fn partial_cmp(&self, other: &H256) -> Option<core::cmp::Ordering> {
158 Some(self.cmp(other))
159 }
160}
161
162impl core::fmt::Debug for H256 {
163 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
164 write!(
165 f,
166 "{:>02x}{:>02x}..{:>02x}{:>02x}",
167 &self[0], &self[1], &self[30], &self[31]
168 )
169 }
170}
171
172impl core::fmt::Display for H256 {
173 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
174 let start = if let Some(precision) = f.precision() {
175 if precision >= 64 {
176 0
177 } else {
178 32 - precision / 2
179 }
180 } else {
181 0
182 };
183 for byte_idx in start..32 {
184 write!(f, "{:>02x}", &self.0[byte_idx])?;
185 }
186 Ok(())
187 }
188}