miden_base/types/
storage.rs1use miden_base_sys::bindings::{
2 StorageSlotId, felt_from_padded_word, padded_word_from_felt, storage,
3};
4use miden_stdlib_sys::{Digest, Felt, Word};
5
6pub trait WordValue: Sized {
11 fn try_into_word(self) -> Result<Word, &'static str>;
13
14 fn try_from_word(word: Word) -> Result<Self, &'static str>;
16}
17
18impl WordValue for Word {
19 fn try_into_word(self) -> Result<Word, &'static str> {
20 Ok(self)
21 }
22
23 fn try_from_word(word: Word) -> Result<Self, &'static str> {
24 Ok(word)
25 }
26}
27
28impl WordValue for Felt {
29 fn try_into_word(self) -> Result<Word, &'static str> {
30 Ok(padded_word_from_felt(self))
31 }
32
33 fn try_from_word(word: Word) -> Result<Self, &'static str> {
34 felt_from_padded_word(word)
35 }
36}
37
38impl WordValue for Digest {
39 fn try_into_word(self) -> Result<Word, &'static str> {
40 Ok(self.into())
41 }
42
43 fn try_from_word(word: Word) -> Result<Self, &'static str> {
44 Ok(word.try_into().unwrap())
45 }
46}
47
48impl WordValue for miden_base_sys::bindings::AccountId {
49 fn try_into_word(self) -> Result<Word, &'static str> {
50 Ok(self.into())
51 }
52
53 fn try_from_word(word: Word) -> Result<Self, &'static str> {
54 word.try_into()
55 }
56}
57
58impl WordValue for miden_base_sys::bindings::Recipient {
59 fn try_into_word(self) -> Result<Word, &'static str> {
60 Ok(self.into())
61 }
62
63 fn try_from_word(word: Word) -> Result<Self, &'static str> {
64 Ok(word.into())
65 }
66}
67
68impl WordValue for miden_base_sys::bindings::Tag {
69 fn try_into_word(self) -> Result<Word, &'static str> {
70 Ok(self.into())
71 }
72
73 fn try_from_word(word: Word) -> Result<Self, &'static str> {
74 word.try_into()
75 }
76}
77
78impl WordValue for miden_base_sys::bindings::NoteIdx {
79 fn try_into_word(self) -> Result<Word, &'static str> {
80 Ok(self.into())
81 }
82
83 fn try_from_word(word: Word) -> Result<Self, &'static str> {
84 word.try_into()
85 }
86}
87
88impl WordValue for miden_base_sys::bindings::NoteType {
89 fn try_into_word(self) -> Result<Word, &'static str> {
90 Ok(self.into())
91 }
92
93 fn try_from_word(word: Word) -> Result<Self, &'static str> {
94 word.try_into()
95 }
96}
97
98pub trait WordKey: Copy {
103 fn try_into_word(self) -> Result<Word, &'static str>;
105}
106
107impl WordKey for Word {
108 fn try_into_word(self) -> Result<Word, &'static str> {
109 Ok(self)
110 }
111}
112
113impl WordKey for Felt {
114 fn try_into_word(self) -> Result<Word, &'static str> {
115 Ok(padded_word_from_felt(self))
116 }
117}
118
119impl WordKey for miden_base_sys::bindings::AccountId {
120 fn try_into_word(self) -> Result<Word, &'static str> {
121 Ok(self.into())
122 }
123}
124
125impl WordKey for miden_base_sys::bindings::Tag {
126 fn try_into_word(self) -> Result<Word, &'static str> {
127 Ok(self.into())
128 }
129}
130
131impl WordKey for miden_base_sys::bindings::NoteIdx {
132 fn try_into_word(self) -> Result<Word, &'static str> {
133 Ok(self.into())
134 }
135}
136
137impl WordKey for miden_base_sys::bindings::NoteType {
138 fn try_into_word(self) -> Result<Word, &'static str> {
139 Ok(self.into())
140 }
141}
142
143#[derive(Debug, Copy, Clone, PartialEq, Eq)]
145pub struct StorageValue<T: WordValue> {
146 pub slot: StorageSlotId,
148 _marker: core::marker::PhantomData<T>,
149}
150
151impl<T: WordValue> StorageValue<T> {
152 pub const fn new(slot: StorageSlotId) -> Self {
154 Self {
155 slot,
156 _marker: core::marker::PhantomData,
157 }
158 }
159}
160
161impl<T: WordValue> From<StorageSlotId> for StorageValue<T> {
162 fn from(slot: StorageSlotId) -> Self {
163 Self::new(slot)
164 }
165}
166
167impl<T: WordValue> StorageValue<T> {
168 #[inline(always)]
170 pub fn get(&self) -> T {
171 T::try_from_word(storage::get_item(self.slot))
172 .unwrap_or_else(|_| panic!("storage slot {:?} contained an invalid word", self.slot))
173 }
174
175 #[inline(always)]
177 pub fn set(&mut self, value: T) -> T {
178 let value = value
179 .try_into_word()
180 .unwrap_or_else(|_| panic!("failed to convert value for storage slot {:?}", self.slot));
181 T::try_from_word(storage::set_item(self.slot, value))
182 .unwrap_or_else(|_| panic!("storage slot {:?} contained an invalid word", self.slot))
183 }
184}
185
186#[derive(Debug, Copy, Clone, PartialEq, Eq)]
188pub struct StorageMap<K: WordKey, V: WordValue> {
189 pub slot: StorageSlotId,
191 _marker: core::marker::PhantomData<(K, V)>,
192}
193
194impl<K: WordKey, V: WordValue> StorageMap<K, V> {
195 pub const fn new(slot: StorageSlotId) -> Self {
197 Self {
198 slot,
199 _marker: core::marker::PhantomData,
200 }
201 }
202}
203
204impl<K: WordKey, V: WordValue> From<StorageSlotId> for StorageMap<K, V> {
205 fn from(slot: StorageSlotId) -> Self {
206 Self::new(slot)
207 }
208}
209
210impl<K: WordKey, V: WordValue> StorageMap<K, V> {
211 #[inline(always)]
216 pub fn get(&self, key: K) -> V {
217 let key = key.try_into_word().unwrap_or_else(|_| {
218 panic!("failed to convert key for storage map slot {:?}", self.slot)
219 });
220 V::try_from_word(storage::get_map_item(self.slot, &key)).unwrap_or_else(|_| {
221 panic!("storage map slot {:?} contained an invalid word", self.slot)
222 })
223 }
224
225 #[inline(always)]
230 pub fn set(&mut self, key: K, value: V) -> V {
231 let key = key.try_into_word().unwrap_or_else(|_| {
232 panic!("failed to convert key for storage map slot {:?}", self.slot)
233 });
234 let value = value.try_into_word().unwrap_or_else(|_| {
235 panic!("failed to convert value for storage map slot {:?}", self.slot)
236 });
237 V::try_from_word(storage::set_map_item(self.slot, key, value)).unwrap_or_else(|_| {
238 panic!("storage map slot {:?} contained an invalid word", self.slot)
239 })
240 }
241}