miniscript_debug/miniscript/
hash256.rs1use core::ops::Index;
21use core::slice::SliceIndex;
22use core::str;
23
24use bitcoin::hashes::{
25 self, borrow_slice_impl, hex, hex_fmt_impl, serde_impl, sha256, Hash as HashTrait,
26};
27
28#[derive(Copy, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
30#[repr(transparent)]
31pub struct Hash([u8; 32]);
32
33hex_fmt_impl!(Debug, Hash);
34hex_fmt_impl!(Display, Hash);
35hex_fmt_impl!(LowerHex, Hash);
36serde_impl!(Hash, 32);
37borrow_slice_impl!(Hash);
38
39impl<I: SliceIndex<[u8]>> Index<I> for Hash {
40 type Output = I::Output;
41
42 #[inline]
43 fn index(&self, index: I) -> &Self::Output {
44 &self.0[index]
45 }
46}
47
48impl str::FromStr for Hash {
49 type Err = hex::Error;
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 hex::FromHex::from_hex(s)
52 }
53}
54
55impl HashTrait for Hash {
56 type Engine = sha256::HashEngine;
57 type Inner = [u8; 32];
58
59 fn engine() -> sha256::HashEngine {
60 sha256::Hash::engine()
61 }
62
63 fn from_engine(e: sha256::HashEngine) -> Hash {
64 let sha2 = sha256::Hash::from_engine(e);
65 let sha2d = sha256::Hash::hash(&sha2[..]);
66
67 let mut ret = [0; 32];
68 ret.copy_from_slice(&sha2d[..]);
69 Hash(ret)
70 }
71
72 const LEN: usize = 32;
73
74 fn from_slice(sl: &[u8]) -> Result<Hash, hashes::Error> {
75 if sl.len() != 32 {
76 Err(hashes::Error::InvalidLength(Self::LEN, sl.len()))
77 } else {
78 let mut ret = [0; 32];
79 ret.copy_from_slice(sl);
80 Ok(Hash(ret))
81 }
82 }
83
84 const DISPLAY_BACKWARD: bool = false;
86
87 fn into_inner(self) -> Self::Inner {
88 self.0
89 }
90
91 fn as_inner(&self) -> &Self::Inner {
92 &self.0
93 }
94
95 fn from_inner(inner: Self::Inner) -> Self {
96 Hash(inner)
97 }
98
99 fn all_zeros() -> Self {
100 Self([0u8; 32])
101 }
102}