oasis_runtime_sdk/storage/
typed.rs1use std::{convert::TryFrom, marker::PhantomData};
2
3use oasis_core_runtime::storage::mkvs;
4
5use super::Store;
6
7pub struct TypedStore<S: Store> {
9 parent: S,
10}
11
12impl<S: Store> TypedStore<S> {
13 pub fn new(parent: S) -> Self {
15 Self { parent }
16 }
17
18 pub fn get<K: AsRef<[u8]>, T: cbor::Decode>(&self, key: K) -> Option<T> {
20 self.parent
21 .get(key.as_ref())
22 .map(|data| cbor::from_slice(&data).unwrap())
23 }
24
25 pub fn insert<K: AsRef<[u8]>, T: cbor::Encode>(&mut self, key: K, value: T) {
27 self.parent.insert(key.as_ref(), &cbor::to_vec(value))
28 }
29
30 pub fn remove<K: AsRef<[u8]>>(&mut self, key: K) {
32 self.parent.remove(key.as_ref())
33 }
34
35 pub fn iter<'store, K, V>(&'store self) -> TypedStoreIterator<'store, K, V>
36 where
37 K: for<'k> TryFrom<&'k [u8]>,
38 V: cbor::Decode + Default,
39 {
40 TypedStoreIterator::new(self.parent.iter())
41 }
42}
43
44pub struct TypedStoreIterator<'store, K, V>
46where
47 K: for<'k> TryFrom<&'k [u8]>,
48 V: Default + cbor::Decode,
49{
50 inner: Box<dyn mkvs::Iterator + 'store>,
51
52 _key: PhantomData<K>,
53 _value: PhantomData<V>,
54}
55
56impl<'store, K, V> TypedStoreIterator<'store, K, V>
57where
58 K: for<'k> TryFrom<&'k [u8]>,
59 V: cbor::Decode + Default,
60{
61 fn new(inner: Box<dyn mkvs::Iterator + 'store>) -> Self {
62 Self {
63 inner,
64 _key: PhantomData,
65 _value: PhantomData,
66 }
67 }
68}
69
70impl<K, V, E> Iterator for TypedStoreIterator<'_, K, V>
71where
72 K: for<'k> TryFrom<&'k [u8], Error = E>,
73 E: std::fmt::Display,
74 V: cbor::Decode + Default,
75{
76 type Item = (K, V);
77
78 fn next(&mut self) -> Option<Self::Item> {
79 Iterator::next(&mut self.inner).map(|(k, v)| {
80 let key = K::try_from(&k).unwrap_or_else(|e| panic!("corrupted storage key: {e}"));
81 let value = if v.is_empty() {
82 Default::default()
84 } else {
85 cbor::from_slice(&v).unwrap()
86 };
87 (key, value)
88 })
89 }
90}