miden_protocol/account/storage/slot/storage_slot.rs
1use crate::Word;
2use crate::account::storage::slot::StorageSlotId;
3use crate::account::{StorageMap, StorageSlotContent, StorageSlotName, StorageSlotType};
4use crate::utils::serde::{
5 ByteReader,
6 ByteWriter,
7 Deserializable,
8 DeserializationError,
9 Serializable,
10};
11
12/// An individual storage slot in [`AccountStorage`](crate::account::AccountStorage).
13///
14/// This consists of a [`StorageSlotName`] that uniquely identifies the slot and its
15/// [`StorageSlotContent`].
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct StorageSlot {
18 /// The name of the storage slot.
19 name: StorageSlotName,
20 /// The content of the storage slot.
21 content: StorageSlotContent,
22}
23
24impl StorageSlot {
25 // CONSTANTS
26 // --------------------------------------------------------------------------------------------
27
28 /// The number of field elements that represent a [`StorageSlot`] in kernel memory.
29 pub const NUM_ELEMENTS: usize = 8;
30
31 // CONSTRUCTORS
32 // --------------------------------------------------------------------------------------------
33
34 /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
35 /// [`StorageSlotContent`].
36 pub fn new(name: StorageSlotName, content: StorageSlotContent) -> Self {
37 Self { name, content }
38 }
39
40 /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and the `value`
41 /// wrapped into a [`StorageSlotContent::Value`].
42 pub fn with_value(name: StorageSlotName, value: Word) -> Self {
43 Self::new(name, StorageSlotContent::Value(value))
44 }
45
46 /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
47 /// [`StorageSlotContent::empty_value`].
48 pub fn with_empty_value(name: StorageSlotName) -> Self {
49 Self::new(name, StorageSlotContent::empty_value())
50 }
51
52 /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and the `map` wrapped
53 /// into a [`StorageSlotContent::Map`]
54 pub fn with_map(name: StorageSlotName, map: StorageMap) -> Self {
55 Self::new(name, StorageSlotContent::Map(map))
56 }
57
58 /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
59 /// [`StorageSlotContent::empty_map`].
60 pub fn with_empty_map(name: StorageSlotName) -> Self {
61 Self::new(name, StorageSlotContent::empty_map())
62 }
63
64 // ACCESSORS
65 // --------------------------------------------------------------------------------------------
66
67 /// Returns the [`StorageSlotName`] by which the [`StorageSlot`] is identified.
68 pub fn name(&self) -> &StorageSlotName {
69 &self.name
70 }
71
72 /// Returns the [`StorageSlotId`] by which the [`StorageSlot`] is identified.
73 pub fn id(&self) -> StorageSlotId {
74 self.name.id()
75 }
76
77 /// Returns this storage slot value as a [Word]
78 ///
79 /// Returns:
80 /// - For [`StorageSlotContent::Value`] the value.
81 /// - For [`StorageSlotContent::Map`] the root of the [StorageMap].
82 pub fn value(&self) -> Word {
83 self.content().value()
84 }
85
86 /// Returns a reference to the [`StorageSlotContent`] contained in this [`StorageSlot`].
87 pub fn content(&self) -> &StorageSlotContent {
88 &self.content
89 }
90
91 /// Returns the [`StorageSlotType`] of this [`StorageSlot`].
92 pub fn slot_type(&self) -> StorageSlotType {
93 self.content.slot_type()
94 }
95
96 // MUTATORS
97 // --------------------------------------------------------------------------------------------
98
99 /// Returns a mutable reference to the [`StorageSlotContent`] contained in this
100 /// [`StorageSlot`].
101 pub fn content_mut(&mut self) -> &mut StorageSlotContent {
102 &mut self.content
103 }
104
105 /// Consumes self and returns the underlying parts.
106 pub fn into_parts(self) -> (StorageSlotName, StorageSlotContent) {
107 (self.name, self.content)
108 }
109}
110
111// SERIALIZATION
112// ================================================================================================
113
114impl Serializable for StorageSlot {
115 fn write_into<W: ByteWriter>(&self, target: &mut W) {
116 target.write(&self.name);
117 target.write(&self.content);
118 }
119
120 fn get_size_hint(&self) -> usize {
121 self.name.get_size_hint() + self.content().get_size_hint()
122 }
123}
124
125impl Deserializable for StorageSlot {
126 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
127 let name: StorageSlotName = source.read()?;
128 let content: StorageSlotContent = source.read()?;
129
130 Ok(Self::new(name, content))
131 }
132}