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 Ok([
99 Felt::new(value.d0).map_err(|_| RpcConversionError::NotAValidFelt)?,
100 Felt::new(value.d1).map_err(|_| RpcConversionError::NotAValidFelt)?,
101 Felt::new(value.d2).map_err(|_| RpcConversionError::NotAValidFelt)?,
102 Felt::new(value.d3).map_err(|_| RpcConversionError::NotAValidFelt)?,
103 ])
104 }
105}
106
107impl TryFrom<proto::primitives::Digest> for Word {
108 type Error = RpcConversionError;
109
110 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
111 Ok(Self::new(value.try_into()?))
112 }
113}
114
115impl TryFrom<&proto::primitives::Digest> for [Felt; 4] {
116 type Error = RpcConversionError;
117
118 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
119 (*value).try_into()
120 }
121}
122
123impl TryFrom<&proto::primitives::Digest> for Word {
124 type Error = RpcConversionError;
125
126 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
127 (*value).try_into()
128 }
129}
130
131impl TryFrom<proto::primitives::Digest> for StorageMapKey {
132 type Error = RpcConversionError;
133
134 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
135 Ok(StorageMapKey::new(value.try_into()?))
136 }
137}