miden_protocol/account/component/storage/schema/
slot.rs1use alloc::collections::BTreeMap;
2use alloc::string::String;
3
4use miden_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
5use miden_processor::DeserializationError;
6
7use super::super::type_registry::{SchemaRequirement, SchemaType};
8use super::super::{InitStorageData, StorageValueName};
9use super::{MapSlotSchema, ValueSlotSchema, WordSchema};
10use crate::account::{StorageSlot, StorageSlotName};
11use crate::errors::ComponentMetadataError;
12
13#[allow(clippy::large_enum_variant)]
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum StorageSlotSchema {
21 Value(ValueSlotSchema),
22 Map(MapSlotSchema),
23}
24
25impl StorageSlotSchema {
26 pub fn value(description: impl Into<String>, word: impl Into<WordSchema>) -> Self {
31 Self::Value(ValueSlotSchema::new(Some(description.into()), word.into()))
32 }
33
34 pub fn map(
36 description: impl Into<String>,
37 key_type: SchemaType,
38 value_type: SchemaType,
39 ) -> Self {
40 Self::Map(MapSlotSchema::new(
41 Some(description.into()),
42 None,
43 WordSchema::new_simple(key_type),
44 WordSchema::new_simple(value_type),
45 ))
46 }
47
48 pub(super) fn collect_init_value_requirements(
49 &self,
50 slot_name: &StorageSlotName,
51 requirements: &mut BTreeMap<StorageValueName, SchemaRequirement>,
52 ) -> Result<(), ComponentMetadataError> {
53 let slot_name = StorageValueName::from_slot_name(slot_name);
54 match self {
55 StorageSlotSchema::Value(slot) => {
56 slot.collect_init_value_requirements(slot_name, requirements)
57 },
58 StorageSlotSchema::Map(_) => Ok(()),
59 }
60 }
61
62 pub fn try_build_storage_slot(
65 &self,
66 slot_name: &StorageSlotName,
67 init_storage_data: &InitStorageData,
68 ) -> Result<StorageSlot, ComponentMetadataError> {
69 match self {
70 StorageSlotSchema::Value(slot) => {
71 let word = slot.try_build_word(init_storage_data, slot_name)?;
72 Ok(StorageSlot::with_value(slot_name.clone(), word))
73 },
74 StorageSlotSchema::Map(slot) => {
75 let storage_map = slot.try_build_map(init_storage_data, slot_name)?;
76 Ok(StorageSlot::with_map(slot_name.clone(), storage_map))
77 },
78 }
79 }
80
81 pub(super) fn validate(&self) -> Result<(), ComponentMetadataError> {
82 match self {
83 StorageSlotSchema::Value(slot) => slot.validate()?,
84 StorageSlotSchema::Map(slot) => slot.validate()?,
85 }
86
87 Ok(())
88 }
89
90 pub(super) fn write_into_with_optional_defaults<W: ByteWriter>(
91 &self,
92 target: &mut W,
93 include_defaults: bool,
94 ) {
95 match self {
96 StorageSlotSchema::Value(slot) => {
97 target.write_u8(0u8);
98 slot.write_into_with_optional_defaults(target, include_defaults);
99 },
100 StorageSlotSchema::Map(slot) => {
101 target.write_u8(1u8);
102 slot.write_into_with_optional_defaults(target, include_defaults);
103 },
104 }
105 }
106}
107
108impl Serializable for StorageSlotSchema {
109 fn write_into<W: ByteWriter>(&self, target: &mut W) {
110 self.write_into_with_optional_defaults(target, true);
111 }
112}
113
114impl Deserializable for StorageSlotSchema {
115 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
116 let variant_tag = source.read_u8()?;
117 match variant_tag {
118 0 => Ok(StorageSlotSchema::Value(ValueSlotSchema::read_from(source)?)),
119 1 => Ok(StorageSlotSchema::Map(MapSlotSchema::read_from(source)?)),
120 _ => Err(DeserializationError::InvalidValue(format!(
121 "unknown variant tag '{variant_tag}' for StorageSlotSchema"
122 ))),
123 }
124 }
125}