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