scsys_crypto/hash/
h160.rs

1/*
2    Appellation: h160 <module>
3    Contrib: @FL03
4*/
5#[cfg(feature = "blake3")]
6mod impl_blake3;
7mod impl_convert;
8mod impl_ops;
9
10/// The H160Hash type is a 20-byte hash.
11pub type H160Hash = [u8; 20];
12
13/// A SHA160 hash type.
14#[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
15#[cfg_attr(
16    feature = "serde",
17    derive(serde::Deserialize, serde::Serialize),
18    serde(default, transparent)
19)]
20#[repr(transparent)]
21pub struct H160(pub H160Hash);
22
23impl H160 {
24    pub fn from_digest(digest: impl AsRef<[u8]>) -> Self {
25        let hash = crate::digest_to_hash::<20>(digest);
26        Self(hash)
27    }
28    #[cfg(feature = "blake3")]
29    pub fn b3(data: impl AsRef<[u8]>) -> Self {
30        let hash = blake3::hash(data.as_ref());
31        Self::from_digest(hash.as_bytes())
32    }
33    #[cfg(feature = "rand")]
34    pub fn random() -> Self {
35        let data = rand::random::<H160Hash>();
36        let mut raw_bytes = [0; 20];
37        raw_bytes.copy_from_slice(&data);
38        (&raw_bytes).into()
39    }
40    /// returns the hash as a slice
41    pub const fn as_slice(&self) -> &[u8] {
42        &self.0
43    }
44    /// returns a mutable reference to the hash as a slice
45    pub fn as_slice_mut(&mut self) -> &mut [u8] {
46        &mut self.0
47    }
48    /// copies the hash into the provided buffer
49    pub fn copy_from_slice(&mut self, value: &[u8]) -> &mut Self {
50        self.0.copy_from_slice(value);
51        self
52    }
53    /// returns the hash as a byte array
54    pub const fn get(&self) -> &H160Hash {
55        &self.0
56    }
57    /// returns a mutable reference to the hash as a byte array
58    pub const fn get_mut(&mut self) -> &mut H160Hash {
59        &mut self.0
60    }
61    /// updates the hash with the provided value
62    pub fn set(&mut self, value: H160Hash) -> &mut Self {
63        *self.get_mut() = value;
64        self
65    }
66    /// [`replace`](core::mem::replace) and return the current value with another
67    pub fn replace(&mut self, value: &H160Hash) -> H160Hash {
68        core::mem::replace(&mut self.0, *value)
69    }
70    /// [`swap`](core::mem::swap) the current value with another
71    pub fn swap(&mut self, other: &mut Self) {
72        core::mem::swap(&mut self.0, &mut other.0)
73    }
74    #[cfg(feature = "alloc")]
75    /// returns a [`Vec<u8>`](alloc::vec::Vec) representation of the hash
76    pub fn to_vec(&self) -> alloc::vec::Vec<u8> {
77        self.get().to_vec()
78    }
79}
80
81impl core::fmt::Debug for H160 {
82    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
83        write!(
84            f,
85            "{:>02x}{:>02x}..{:>02x}{:>02x}",
86            &self[0], &self[1], &self[18], &self[19]
87        )
88    }
89}
90
91impl core::fmt::Display for H160 {
92    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
93        let start = if let Some(precision) = f.precision() {
94            if precision >= 64 {
95                0
96            } else {
97                20 - precision / 2
98            }
99        } else {
100            0
101        };
102        for byte_idx in start..20 {
103            write!(f, "{:>02x}", &self.0[byte_idx])?;
104        }
105        Ok(())
106    }
107}
108
109impl AsRef<[u8]> for H160 {
110    #[inline]
111    fn as_ref(&self) -> &[u8] {
112        &self.0
113    }
114}
115
116impl AsMut<[u8]> for H160 {
117    #[inline]
118    fn as_mut(&mut self) -> &mut [u8] {
119        &mut self.0
120    }
121}
122
123impl core::borrow::Borrow<[u8]> for H160 {
124    #[inline]
125    fn borrow(&self) -> &[u8] {
126        &self.0
127    }
128}
129
130impl core::borrow::BorrowMut<[u8]> for H160 {
131    #[inline]
132    fn borrow_mut(&mut self) -> &mut [u8] {
133        &mut self.0
134    }
135}
136
137impl core::ops::Deref for H160 {
138    type Target = [u8; 20];
139
140    #[inline]
141    fn deref(&self) -> &Self::Target {
142        &self.0
143    }
144}
145
146impl core::ops::DerefMut for H160 {
147    #[inline]
148    fn deref_mut(&mut self) -> &mut Self::Target {
149        &mut self.0
150    }
151}