ic_memory/slot/descriptor.rs
1use crate::validation::Validate;
2use serde::{Deserialize, Serialize};
3
4///
5/// AllocationSlot
6///
7/// Durable physical allocation identity interpreted by a storage substrate.
8///
9/// Stable keys are logical identities; allocation slots are the physical
10/// locations those keys are bound to in the ledger.
11#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
12pub enum AllocationSlot {
13 /// `ic-stable-structures::MemoryManager` virtual memory ID.
14 MemoryManagerId(u8),
15 /// Named substrate partition.
16 NamedPartition(String),
17 /// Forward-compatible custom slot descriptor.
18 Custom {
19 /// Substrate-defined slot kind.
20 kind: String,
21 /// Slot descriptor version.
22 version: u32,
23 /// Canonical substrate-defined value.
24 value: Vec<u8>,
25 },
26}
27
28///
29/// AllocationSlotDescriptor
30///
31/// Encoded allocation slot persisted in the ledger.
32///
33/// Constructors for built-in substrates validate their invariants before a
34/// descriptor can be used publicly. For `MemoryManager` slots, use
35/// [`AllocationSlotDescriptor::memory_manager`] so ID 255 is rejected.
36#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
37pub struct AllocationSlotDescriptor {
38 /// Durable allocation slot.
39 pub(crate) slot: AllocationSlot,
40 /// Substrate identifier that interprets the slot.
41 pub(crate) substrate: String,
42 /// Descriptor encoding version.
43 pub(crate) descriptor_version: u32,
44}
45
46impl AllocationSlotDescriptor {
47 /// Return the durable allocation slot value.
48 #[must_use]
49 pub const fn slot(&self) -> &AllocationSlot {
50 &self.slot
51 }
52
53 /// Return the substrate identifier that interprets this slot.
54 #[must_use]
55 pub fn substrate(&self) -> &str {
56 &self.substrate
57 }
58
59 /// Return the descriptor encoding version.
60 #[must_use]
61 pub const fn descriptor_version(&self) -> u32 {
62 self.descriptor_version
63 }
64}
65
66impl Validate for AllocationSlotDescriptor {
67 type Error = AllocationSlotDescriptorError;
68
69 fn validate(&self) -> Result<(), Self::Error> {
70 if matches!(self.slot, AllocationSlot::MemoryManagerId(_))
71 || self.substrate == super::memory_manager::MEMORY_MANAGER_SUBSTRATE
72 {
73 self.memory_manager_id()
74 .map_err(AllocationSlotDescriptorError::MemoryManager)?;
75 }
76
77 Ok(())
78 }
79}
80
81///
82/// AllocationSlotDescriptorError
83///
84/// Allocation slot descriptor validation failure.
85#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
86pub enum AllocationSlotDescriptorError {
87 /// `MemoryManager` descriptor invariants failed.
88 #[error(transparent)]
89 MemoryManager(super::memory_manager::MemoryManagerSlotError),
90}