miden_protocol/account/patch/storage/
slot_patch.rs1use crate::account::{
2 StorageMapPatch,
3 StorageMapPatchEntries,
4 StoragePatchOperation,
5 StorageSlotContent,
6 StorageSlotName,
7 StorageSlotType,
8 StorageValuePatch,
9};
10use crate::errors::AccountPatchError;
11use crate::utils::serde::{
12 ByteReader,
13 ByteWriter,
14 Deserializable,
15 DeserializationError,
16 Serializable,
17};
18
19#[derive(Debug, Clone, PartialEq, Eq)]
27pub enum StorageSlotPatch {
28 Value(StorageValuePatch),
29 Map(StorageMapPatch),
30}
31
32impl StorageSlotPatch {
33 const VALUE: u8 = 0;
38
39 const MAP: u8 = 1;
41
42 pub fn slot_type(&self) -> StorageSlotType {
47 match self {
48 StorageSlotPatch::Value(_) => StorageSlotType::Value,
49 StorageSlotPatch::Map(_) => StorageSlotType::Map,
50 }
51 }
52
53 pub fn patch_op(&self) -> StoragePatchOperation {
55 match self {
56 StorageSlotPatch::Value(value_patch) => value_patch.patch_op(),
57 StorageSlotPatch::Map(map_patch) => map_patch.patch_op(),
58 }
59 }
60
61 pub fn is_value(&self) -> bool {
63 matches!(self, Self::Value(_))
64 }
65
66 pub fn is_map(&self) -> bool {
68 matches!(self, Self::Map(_))
69 }
70
71 pub(super) fn merge(
83 &mut self,
84 slot_name: &StorageSlotName,
85 other: Self,
86 ) -> Result<MergeOutcome, AccountPatchError> {
87 match (self, other) {
88 (StorageSlotPatch::Value(current), StorageSlotPatch::Value(new)) => {
89 current.merge(slot_name, new)
90 },
91 (StorageSlotPatch::Map(current), StorageSlotPatch::Map(new)) => {
92 current.merge(slot_name, new)
93 },
94 (..) => Err(AccountPatchError::StorageSlotUsedAsDifferentTypes(slot_name.clone())),
95 }
96 }
97}
98
99impl From<StorageSlotContent> for StorageSlotPatch {
100 fn from(content: StorageSlotContent) -> Self {
103 match content {
104 StorageSlotContent::Value(value) => {
105 StorageSlotPatch::Value(StorageValuePatch::Create { value })
106 },
107 StorageSlotContent::Map(storage_map) => {
108 StorageSlotPatch::Map(StorageMapPatch::Create {
109 entries: StorageMapPatchEntries::from(storage_map),
110 })
111 },
112 }
113 }
114}
115
116impl Serializable for StorageSlotPatch {
117 fn write_into<W: ByteWriter>(&self, target: &mut W) {
118 match self {
119 StorageSlotPatch::Value(value_patch) => {
120 target.write_u8(Self::VALUE);
121 target.write(value_patch);
122 },
123 StorageSlotPatch::Map(map_patch) => {
124 target.write_u8(Self::MAP);
125 target.write(map_patch);
126 },
127 }
128 }
129
130 fn get_size_hint(&self) -> usize {
131 let tag_size = 0u8.get_size_hint();
132 match self {
133 StorageSlotPatch::Value(value_patch) => tag_size + value_patch.get_size_hint(),
134 StorageSlotPatch::Map(map_patch) => tag_size + map_patch.get_size_hint(),
135 }
136 }
137}
138
139impl Deserializable for StorageSlotPatch {
140 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
141 match source.read_u8()? {
142 Self::VALUE => Ok(Self::Value(source.read()?)),
143 Self::MAP => Ok(Self::Map(source.read()?)),
144 other => Err(DeserializationError::InvalidValue(format!(
145 "unknown storage slot patch variant {other}"
146 ))),
147 }
148 }
149}
150
151pub(super) enum MergeOutcome {
161 Keep,
163 Remove,
165}