1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use fadroma_platform_scrt::cosmwasm_std::{
Storage, ReadonlyStorage, StdResult, to_vec, from_slice
};
use serde::{Serialize, de::DeserializeOwned};
use crate::storage::concat;
pub trait Readonly <S: ReadonlyStorage> {
fn storage (&self) -> &S;
fn load <T: DeserializeOwned> (&self, key: &[u8]) -> StdResult<Option<T>> {
match self.storage().get(key) {
Some(data) => from_slice(&data),
None => Ok(None)
}
}
fn load_ns <T: DeserializeOwned> (&self, ns: &[u8], key: &[u8]) -> StdResult<Option<T>> {
self.load(&concat(ns, key))
}
}
pub trait Writable <S: Storage>: Readonly<S> {
fn storage_mut (&mut self) -> &mut S;
fn save <T: Serialize> (&mut self, key: &[u8], val: T) -> StdResult<&mut Self> {
self.storage_mut().set(&key, &to_vec(&val)?);
Ok(self)
}
fn save_ns <T: Serialize> (&mut self, ns: &[u8], key: &[u8], val: T) -> StdResult<&mut Self> {
self.save(&concat(ns, key), val)
}
}
#[macro_export] macro_rules! stateful {
(
$Obj:ident ($($storage:tt)+):
$Readonly:ident { $($readonlies:tt)* }
$Writable:ident { $($writables:tt)* }
) => {
impl<S: ReadonlyStorage> $Readonly<S> for $Obj<&S> {
fn storage (&self) -> &S { &self.$($storage)+ }
}
impl<S: ReadonlyStorage> $Readonly<S> for $Obj<&mut S> {
fn storage (&self) -> &S { &self.$($storage)+ }
}
impl<S: Storage> $Writable<S> for $Obj<&mut S> {
fn storage_mut (&mut self) -> &mut S { &mut self.$($storage)+ }
}
impl<S: ReadonlyStorage> $Obj<&S> {
$($readonlies)*
}
impl<S: Storage> $Obj<&mut S> {
$($readonlies)*
$($writables)*
}
};
}