1use std::str::FromStr;
2
3use derive_more::{From, Into};
4use pyo3::prelude::*;
5use serde::{Deserialize, Serialize};
6use solana_program::hash::{
7 hash, Hash as HashOriginal, ParseHashError as ParseHashErrorOriginal, HASH_BYTES,
8};
9use solders_macros::{common_methods, pyhash, richcmp_full};
10
11use solders_traits::handle_py_err;
12use solders_traits_core::{
13 impl_display, pybytes_general_via_slice, CommonMethodsCore, PyFromBytesGeneral, PyHash,
14 RichcmpFull,
15};
16
17#[pyclass(module = "solders.hash", subclass)]
18#[derive(
24 Clone,
25 Copy,
26 Default,
27 Eq,
28 PartialEq,
29 Ord,
30 PartialOrd,
31 Hash,
32 Debug,
33 Deserialize,
34 Serialize,
35 From,
36 Into,
37)]
38pub struct Hash(HashOriginal);
39
40#[pyhash]
41#[richcmp_full]
42#[common_methods]
43#[pymethods]
44impl Hash {
45 #[classattr]
46 pub const LENGTH: usize = HASH_BYTES;
47
48 #[new]
49 pub fn new(hash_bytes: [u8; HASH_BYTES]) -> Self {
50 HashOriginal::new_from_array(hash_bytes).into()
51 }
52
53 #[staticmethod]
54 #[pyo3(name = "from_string")]
55 pub fn new_from_string(s: &str) -> PyResult<Self> {
72 handle_py_err(HashOriginal::from_str(s))
73 }
74
75 #[staticmethod]
76 pub fn new_unique() -> Self {
81 HashOriginal::new_unique().into()
82 }
83
84 #[staticmethod]
85 #[pyo3(name = "default")]
86 pub fn new_default() -> Self {
97 Self::default()
98 }
99
100 #[staticmethod]
101 #[allow(clippy::self_named_constructors)]
102 pub fn hash(val: &[u8]) -> Self {
117 hash(val).into()
118 }
119
120 #[staticmethod]
121 pub fn from_bytes(raw_bytes: [u8; HASH_BYTES]) -> PyResult<Self> {
130 Self::py_from_bytes(&raw_bytes)
131 }
132}
133
134impl PyFromBytesGeneral for Hash {
135 fn py_from_bytes_general(raw: &[u8]) -> PyResult<Self> {
136 Ok(HashOriginal::new(raw).into())
137 }
138}
139
140pybytes_general_via_slice!(Hash);
141solders_traits_core::common_methods_default!(Hash);
142
143impl RichcmpFull for Hash {}
144
145impl PyHash for Hash {}
146
147impl AsRef<HashOriginal> for Hash {
148 fn as_ref(&self) -> &HashOriginal {
149 &self.0
150 }
151}
152
153impl AsRef<[u8]> for Hash {
154 fn as_ref(&self) -> &[u8] {
155 self.0.as_ref()
156 }
157}
158
159impl FromStr for Hash {
160 type Err = ParseHashErrorOriginal;
161 fn from_str(s: &str) -> Result<Self, Self::Err> {
162 HashOriginal::from_str(s).map(Hash::from)
163 }
164}
165
166impl_display!(Hash);