1use revm::Database;
2
3use crate::{backed_types::StorageBackedUint64, storage::Storage};
4
5const LENGTH_OFFSET: u64 = 0;
6
7pub struct SubStorageVector<D> {
11 storage: Storage<D>,
12 length: StorageBackedUint64<D>,
13}
14
15pub fn open_sub_storage_vector<D: Database>(storage: Storage<D>) -> SubStorageVector<D> {
16 let state = storage.state_ptr();
17 let base_key = storage.base_key();
18 SubStorageVector {
19 length: StorageBackedUint64::new(state, base_key, LENGTH_OFFSET),
20 storage,
21 }
22}
23
24impl<D: Database> SubStorageVector<D> {
25 pub fn length(&self) -> Result<u64, ()> {
26 self.length.get()
27 }
28
29 pub fn at(&self, index: u64) -> Storage<D> {
31 self.storage.open_sub_storage(&index.to_be_bytes())
32 }
33
34 pub fn push(&self) -> Result<Storage<D>, ()> {
36 let len = self.length.get()?;
37 self.length.set(len + 1)?;
38 Ok(self.at(len))
39 }
40
41 pub fn pop(&self) -> Result<Option<u64>, ()> {
43 let len = self.length.get()?;
44 if len == 0 {
45 return Ok(None);
46 }
47 let new_len = len - 1;
48 self.length.set(new_len)?;
49 Ok(Some(new_len))
50 }
51}