Skip to main content

miden_client/rpc/domain/
digest.rs

1use 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
12// FORMATTING
13// ================================================================================================
14
15impl 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
59// INTO
60// ================================================================================================
61
62impl 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
91// FROM DIGEST
92// ================================================================================================
93
94impl 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}