1use crate::{
2 declaration::AllocationDeclaration, key::StableKey, slot::AllocationSlotDescriptor,
3 substrate::StorageSubstrate,
4};
5use std::sync::Arc;
6
7#[derive(Clone, Debug, Eq, PartialEq)]
22pub struct ValidatedAllocations {
23 inner: Arc<ValidatedState>,
24 _private: (),
25}
26
27#[derive(Clone, Debug, Eq, PartialEq)]
28struct ValidatedState {
29 generation: u64,
31 declarations: Vec<AllocationDeclaration>,
33 runtime_fingerprint: Option<String>,
35}
36
37impl ValidatedAllocations {
38 pub(crate) fn new(
39 generation: u64,
40 declarations: Vec<AllocationDeclaration>,
41 runtime_fingerprint: Option<String>,
42 ) -> Self {
43 Self {
44 inner: Arc::new(ValidatedState {
45 generation,
46 declarations,
47 runtime_fingerprint,
48 }),
49 _private: (),
50 }
51 }
52
53 pub(crate) fn with_generation(self, generation: u64) -> Self {
54 let mut state = (*self.inner).clone();
55 state.generation = generation;
56 Self {
57 inner: Arc::new(state),
58 _private: (),
59 }
60 }
61
62 pub(crate) fn without_stable_key(self, stable_key: &str) -> Self {
63 let mut state = (*self.inner).clone();
64 state
65 .declarations
66 .retain(|declaration| declaration.stable_key.as_str() != stable_key);
67 Self {
68 inner: Arc::new(state),
69 _private: (),
70 }
71 }
72
73 #[must_use]
75 pub fn generation(&self) -> u64 {
76 self.inner.generation
77 }
78
79 #[must_use]
81 pub fn declarations(&self) -> &[AllocationDeclaration] {
82 &self.inner.declarations
83 }
84
85 #[must_use]
87 pub fn runtime_fingerprint(&self) -> Option<&str> {
88 self.inner.runtime_fingerprint.as_deref()
89 }
90
91 #[must_use]
93 pub fn slot_for(&self, key: &StableKey) -> Option<&AllocationSlotDescriptor> {
94 self.declarations()
95 .iter()
96 .find(|declaration| &declaration.stable_key == key)
97 .map(|declaration| &declaration.slot)
98 }
99}
100
101pub struct AllocationSession<S: StorageSubstrate> {
111 substrate: S,
112 validated: ValidatedAllocations,
113}
114
115impl<S: StorageSubstrate> AllocationSession<S> {
116 #[must_use]
118 pub const fn new(substrate: S, validated: ValidatedAllocations) -> Self {
119 Self {
120 substrate,
121 validated,
122 }
123 }
124
125 #[must_use]
127 pub const fn validated(&self) -> &ValidatedAllocations {
128 &self.validated
129 }
130
131 pub fn open(
133 &self,
134 key: &StableKey,
135 ) -> Result<S::MemoryHandle, AllocationSessionError<S::Error>> {
136 let slot = self
137 .validated
138 .slot_for(key)
139 .ok_or_else(|| AllocationSessionError::UnknownStableKey(key.clone()))?;
140 self.substrate
141 .open_slot(slot)
142 .map_err(AllocationSessionError::Substrate)
143 }
144}
145
146#[non_exhaustive]
151#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
152pub enum AllocationSessionError<E> {
153 #[error("stable key '{0}' was not validated for this allocation session")]
155 UnknownStableKey(StableKey),
156 #[error("storage substrate failed to open allocation slot")]
158 Substrate(E),
159}