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 #[must_use]
64 pub fn generation(&self) -> u64 {
65 self.inner.generation
66 }
67
68 #[must_use]
70 pub fn declarations(&self) -> &[AllocationDeclaration] {
71 &self.inner.declarations
72 }
73
74 #[must_use]
76 pub fn runtime_fingerprint(&self) -> Option<&str> {
77 self.inner.runtime_fingerprint.as_deref()
78 }
79
80 #[must_use]
82 pub fn slot_for(&self, key: &StableKey) -> Option<&AllocationSlotDescriptor> {
83 self.declarations()
84 .iter()
85 .find(|declaration| &declaration.stable_key == key)
86 .map(|declaration| &declaration.slot)
87 }
88}
89
90pub struct AllocationSession<S: StorageSubstrate> {
100 substrate: S,
101 validated: ValidatedAllocations,
102}
103
104impl<S: StorageSubstrate> AllocationSession<S> {
105 #[must_use]
107 pub const fn new(substrate: S, validated: ValidatedAllocations) -> Self {
108 Self {
109 substrate,
110 validated,
111 }
112 }
113
114 #[must_use]
116 pub const fn validated(&self) -> &ValidatedAllocations {
117 &self.validated
118 }
119
120 pub fn open(
122 &self,
123 key: &StableKey,
124 ) -> Result<S::MemoryHandle, AllocationSessionError<S::Error>> {
125 let slot = self
126 .validated
127 .slot_for(key)
128 .ok_or_else(|| AllocationSessionError::UnknownStableKey(key.clone()))?;
129 self.substrate
130 .open_slot(slot)
131 .map_err(AllocationSessionError::Substrate)
132 }
133}
134
135#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
140pub enum AllocationSessionError<E> {
141 #[error("stable key '{0}' was not validated for this allocation session")]
143 UnknownStableKey(StableKey),
144 #[error("storage substrate failed to open allocation slot")]
146 Substrate(E),
147}