miden_client/rpc/domain/
digest.rs1use alloc::string::String;
2use alloc::vec::Vec;
3use core::fmt::{self, Debug, Display, Formatter};
4
5use hex::ToHex;
6use miden_protocol::note::NoteId;
7use miden_protocol::{Felt, StarkField, 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 let mut data: Vec<char> = Vec::with_capacity(Word::SERIALIZED_SIZE);
40 data.extend(format!("{:016x}", self.d0).chars());
41 data.extend(format!("{:016x}", self.d1).chars());
42 data.extend(format!("{:016x}", self.d2).chars());
43 data.extend(format!("{:016x}", self.d3).chars());
44 data.into_iter().collect()
45 }
46
47 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
48 let mut data: Vec<char> = Vec::with_capacity(Word::SERIALIZED_SIZE);
49 data.extend(format!("{:016X}", self.d0).chars());
50 data.extend(format!("{:016X}", self.d1).chars());
51 data.extend(format!("{:016X}", self.d2).chars());
52 data.extend(format!("{:016X}", self.d3).chars());
53 data.into_iter().collect()
54 }
55}
56
57impl From<Word> for proto::primitives::Digest {
61 fn from(value: Word) -> Self {
62 Self {
63 d0: value[0].as_int(),
64 d1: value[1].as_int(),
65 d2: value[2].as_int(),
66 d3: value[3].as_int(),
67 }
68 }
69}
70
71impl From<&Word> for proto::primitives::Digest {
72 fn from(value: &Word) -> Self {
73 (*value).into()
74 }
75}
76
77impl From<&NoteId> for proto::primitives::Digest {
78 fn from(value: &NoteId) -> Self {
79 value.as_word().into()
80 }
81}
82
83impl From<NoteId> for proto::primitives::Digest {
84 fn from(value: NoteId) -> Self {
85 value.as_word().into()
86 }
87}
88
89impl TryFrom<proto::primitives::Digest> for [Felt; 4] {
93 type Error = RpcConversionError;
94
95 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
96 if [value.d0, value.d1, value.d2, value.d3]
97 .iter()
98 .all(|v| *v < <Felt as StarkField>::MODULUS)
99 {
100 Ok([
101 Felt::new(value.d0),
102 Felt::new(value.d1),
103 Felt::new(value.d2),
104 Felt::new(value.d3),
105 ])
106 } else {
107 Err(RpcConversionError::NotAValidFelt)
108 }
109 }
110}
111
112impl TryFrom<proto::primitives::Digest> for Word {
113 type Error = RpcConversionError;
114
115 fn try_from(value: proto::primitives::Digest) -> Result<Self, Self::Error> {
116 Ok(Self::new(value.try_into()?))
117 }
118}
119
120impl TryFrom<&proto::primitives::Digest> for [Felt; 4] {
121 type Error = RpcConversionError;
122
123 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
124 (*value).try_into()
125 }
126}
127
128impl TryFrom<&proto::primitives::Digest> for Word {
129 type Error = RpcConversionError;
130
131 fn try_from(value: &proto::primitives::Digest) -> Result<Self, Self::Error> {
132 (*value).try_into()
133 }
134}