cardano_sdk/cardano/
hash.rs1use crate::{cbor, pallas};
6use anyhow::anyhow;
7use std::{fmt, str::FromStr};
8
9#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, cbor::Encode, cbor::Decode)]
53#[repr(transparent)]
54#[cbor(transparent)]
55pub struct Hash<const SIZE: usize>(#[n(0)] pallas::Hash<SIZE>);
56
57impl<const SIZE: usize> fmt::Display for Hash<SIZE> {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
59 self.0.fmt(f)
60 }
61}
62
63impl Hash<28> {
66 pub fn new<T: AsRef<[u8]>>(preimage: T) -> Self {
67 Self(pallas::Hasher::<224>::hash(preimage.as_ref()))
68 }
69}
70
71impl Hash<32> {
72 pub fn new<T: AsRef<[u8]>>(preimage: T) -> Self {
73 Self(pallas::Hasher::<256>::hash(preimage.as_ref()))
74 }
75}
76
77impl<const SIZE: usize> Hash<SIZE> {
80 pub const SIZE: usize = SIZE;
81}
82
83impl<const SIZE: usize> TryFrom<&str> for Hash<SIZE> {
86 type Error = anyhow::Error;
87
88 fn try_from(s: &str) -> anyhow::Result<Self> {
89 let bytes = hex::decode(s).map_err(|e| anyhow!(e))?;
90 let fixed_sized_bytes = <[u8; SIZE]>::try_from(bytes).map_err(|_| {
91 anyhow!(
92 "invalid hex string length; expected {}, got {}",
93 2 * SIZE,
94 s.len()
95 )
96 })?;
97
98 Ok(Hash(pallas::Hash::new(fixed_sized_bytes)))
99 }
100}
101
102impl<const SIZE: usize> FromStr for Hash<SIZE> {
103 type Err = String;
104
105 fn from_str(s: &str) -> Result<Self, Self::Err> {
106 Self::try_from(s).map_err(|e| e.to_string())
107 }
108}
109
110impl<const SIZE: usize> TryFrom<Vec<u8>> for Hash<SIZE> {
111 type Error = anyhow::Error;
112
113 fn try_from(bytes: Vec<u8>) -> anyhow::Result<Self> {
114 let fixed_sized_bytes = <[u8; SIZE]>::try_from(bytes.as_slice()).map_err(|_| {
115 anyhow!(
116 "invalid bytes sequence length; expected {} bytes, got {} bytes",
117 SIZE,
118 bytes.len(),
119 )
120 })?;
121
122 Ok(Hash(pallas::Hash::new(fixed_sized_bytes)))
123 }
124}
125
126impl<const SIZE: usize> From<[u8; SIZE]> for Hash<SIZE> {
127 fn from(hash: [u8; SIZE]) -> Self {
128 Self::from(pallas::Hash::from(hash))
129 }
130}
131
132impl<const SIZE: usize> From<pallas::Hash<SIZE>> for Hash<SIZE> {
133 fn from(hash: pallas::Hash<SIZE>) -> Self {
134 Self(hash)
135 }
136}
137
138impl<const SIZE: usize> From<&pallas::Hash<SIZE>> for Hash<SIZE> {
139 fn from(hash: &pallas::Hash<SIZE>) -> Self {
140 Self(*hash)
141 }
142}
143
144impl<const SIZE: usize> From<Hash<SIZE>> for pallas::Hash<SIZE> {
147 fn from(hash: Hash<SIZE>) -> Self {
148 hash.0
149 }
150}
151
152impl<const SIZE: usize> From<&Hash<SIZE>> for pallas::Hash<SIZE> {
153 fn from(hash: &Hash<SIZE>) -> Self {
154 hash.0
155 }
156}
157
158impl<const SIZE: usize> From<Hash<SIZE>> for [u8; SIZE] {
159 fn from(hash: Hash<SIZE>) -> Self {
160 *hash.0
161 }
162}
163
164impl<const SIZE: usize> AsRef<[u8]> for Hash<SIZE> {
165 fn as_ref(&self) -> &[u8] {
166 self.0.as_ref()
167 }
168}
169
170#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, cbor::Encode, cbor::Decode)]
171#[repr(transparent)]
172#[cbor(transparent)]
173pub struct Hash28(#[n(0)] Hash<28>);
174
175impl From<Hash<28>> for Hash28 {
176 fn from(hash28: Hash<28>) -> Self {
177 Self(hash28)
178 }
179}
180
181impl std::ops::Deref for Hash28 {
182 type Target = Hash<28>;
183 fn deref(&self) -> &Self::Target {
184 &self.0
185 }
186}
187
188#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, cbor::Encode, cbor::Decode)]
189#[repr(transparent)]
190#[cbor(transparent)]
191pub struct Hash32(#[n(0)] Hash<32>);
192
193impl From<Hash<32>> for Hash32 {
194 fn from(hash32: Hash<32>) -> Self {
195 Self(hash32)
196 }
197}
198
199impl std::ops::Deref for Hash32 {
200 type Target = Hash<32>;
201 fn deref(&self) -> &Self::Target {
202 &self.0
203 }
204}
205
206#[cfg(any(test, feature = "test-utils"))]
207pub mod tests {
208 use crate::Hash;
209 use proptest::prelude::*;
210
211 pub mod generators {
214 use super::*;
215
216 pub fn hash28() -> impl Strategy<Value = Hash<28>> {
217 any::<[u8; 28]>().prop_map(Hash::from)
218 }
219
220 pub fn hash32() -> impl Strategy<Value = Hash<32>> {
221 any::<[u8; 32]>().prop_map(Hash::from)
222 }
223 }
224}