miden_client/rpc/domain/
digest.rs1use alloc::string::String;
2use core::fmt::{self, Debug, Display, Formatter};
3
4use hex::ToHex;
5use miden_protocol::account::StorageMapKey;
6use miden_protocol::note::NoteId;
7use miden_protocol::{Felt, Word};
8
9use crate::rpc::errors::RpcConversionError;
10use crate::rpc::generated as proto;
11
12impl Display for proto::primitives::Digest {
16 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
17 f.write_str(&self.encode_hex::<String>())
18 }
19}
20
21impl Debug for proto::primitives::Digest {
22 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 Display::fmt(self, f)
24 }
25}
26
27impl ToHex for &proto::primitives::Digest {
28 fn encode_hex<T: FromIterator<char>>(&self) -> T {
29 (*self).encode_hex()
30 }
31
32 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
33 (*self).encode_hex_upper()
34 }
35}
36
37impl ToHex for proto::primitives::Digest {
38 fn encode_hex<T: FromIterator<char>>(&self) -> T {
39 const HEX_LOWER: [char; 16] =
40 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
41 [self.d0, self.d1, self.d2, self.d3]
42 .into_iter()
43 .flat_map(u64::to_be_bytes)
44 .flat_map(|b| [HEX_LOWER[(b >> 4) as usize], HEX_LOWER[(b & 0xf) as usize]])
45 .collect()
46 }
47
48 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
49 const HEX_UPPER: [char; 16] =
50 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
51 [self.d0, self.d1, self.d2, self.d3]
52 .into_iter()
53 .flat_map(u64::to_be_bytes)
54 .flat_map(|b| [HEX_UPPER[(b >> 4) as usize], HEX_UPPER[(b & 0xf) as usize]])
55 .collect()
56 }
57}
58
59impl From<Word> for proto::primitives::Digest {
63 fn from(value: Word) -> Self {
64 Self {
65 d0: value[0].as_canonical_u64(),
66 d1: value[1].as_canonical_u64(),
67 d2: value[2].as_canonical_u64(),
68 d3: value[3].as_canonical_u64(),
69 }
70 }
71}
72
73impl From<&Word> for proto::primitives::Digest {
74 fn from(value: &Word) -> Self {
75 (*value).into()
76 }
77}
78
79impl From<&NoteId> for proto::primitives::Digest {
80 fn from(value: &NoteId) -> Self {
81 value.as_word().into()
82 }
83}
84
85impl From<NoteId> for proto::primitives::Digest {
86 fn from(value: NoteId) -> Self {
87 value.as_word().into()
88 }
89}
90
91impl TryFrom<proto::primitives::Digest> for [Felt; 4] {
95 type Error = RpcConversionError;
96
97 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
98 if [value.d0, value.d1, value.d2, value.d3].iter().all(|v| *v < Felt::ORDER) {
99 Ok([
100 Felt::new(value.d0),
101 Felt::new(value.d1),
102 Felt::new(value.d2),
103 Felt::new(value.d3),
104 ])
105 } else {
106 Err(RpcConversionError::NotAValidFelt)
107 }
108 }
109}
110
111impl TryFrom<proto::primitives::Digest> for Word {
112 type Error = RpcConversionError;
113
114 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
115 Ok(Self::new(value.try_into()?))
116 }
117}
118
119impl TryFrom<&proto::primitives::Digest> for [Felt; 4] {
120 type Error = RpcConversionError;
121
122 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
123 (*value).try_into()
124 }
125}
126
127impl TryFrom<&proto::primitives::Digest> for Word {
128 type Error = RpcConversionError;
129
130 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
131 (*value).try_into()
132 }
133}
134
135impl TryFrom<proto::primitives::Digest> for StorageMapKey {
136 type Error = RpcConversionError;
137
138 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
139 Ok(StorageMapKey::new(value.try_into()?))
140 }
141}