1use crate::arithmetic::{OverflowingAdd, OverflowingSub};
2use crate::casper_types::{
3 bytesrepr::{FromBytes, ToBytes},
4 CLTyped
5};
6use crate::module::{ModuleComponent, ModulePrimitive};
7use crate::prelude::*;
8use crate::ContractEnv;
9use core::fmt::Debug;
10
11pub struct Mapping<K, V> {
13 parent_env: Rc<ContractEnv>,
14 phantom: core::marker::PhantomData<(K, V)>,
15 index: u8
16}
17
18impl<K: ToBytes, V> ModuleComponent for Mapping<K, V> {
19 fn instance(env: Rc<ContractEnv>, index: u8) -> Self {
21 Self {
22 parent_env: env,
23 phantom: core::marker::PhantomData,
24 index
25 }
26 }
27}
28
29impl<K: ToBytes, V> Revertible for Mapping<K, V> {
30 fn revert<E: Into<OdraError>>(&self, e: E) -> ! {
31 self.parent_env.revert(e)
32 }
33}
34
35impl<K: ToBytes, V> ModulePrimitive for Mapping<K, V> {}
36
37impl<K: ToBytes, V> Mapping<K, V> {
38 fn env_for_key(&self, key: &K) -> ContractEnv {
39 let mut env = (*self.parent_env).clone();
40 let key = key.to_bytes().unwrap_or_default();
41 env.add_to_mapping_data(&key);
42 env
43 }
44}
45
46impl<K: ToBytes, V: FromBytes + CLTyped> Mapping<K, V> {
47 pub fn get(&self, key: &K) -> Option<V> {
51 let env = self.env_for_key(key);
52 Var::<V>::instance(Rc::new(env), self.index).get()
53 }
54}
55
56impl<K: ToBytes, V: FromBytes + CLTyped + Default> Mapping<K, V> {
57 pub fn get_or_default(&self, key: &K) -> V {
60 let env = self.env_for_key(key);
61 Var::<V>::instance(Rc::new(env), self.index).get_or_default()
62 }
63}
64
65impl<K: ToBytes, V: ToBytes + CLTyped> Mapping<K, V> {
66 pub fn set(&mut self, key: &K, value: V) {
68 let env = self.env_for_key(key);
69 Var::<V>::instance(Rc::new(env), self.index).set(value)
70 }
71}
72
73impl<K: ToBytes, V: Module> Mapping<K, V> {
74 pub fn module(&self, key: &K) -> SubModule<V> {
78 let env = self.env_for_key(key);
79 SubModule::instance(Rc::new(env), self.index)
80 }
81}
82
83impl<K: ToBytes, V: ToBytes + FromBytes + CLTyped + OverflowingAdd + Default> Mapping<K, V> {
84 pub fn add(&mut self, key: &K, value: V) {
89 let env = self.env_for_key(key);
90 let mut var = Var::<V>::instance(Rc::new(env), self.index);
91 var.add(value);
92 }
93}
94
95impl<
96 K: ToBytes,
97 V: ToBytes + FromBytes + CLTyped + OverflowingSub + Default + Debug + PartialOrd
98 > Mapping<K, V>
99{
100 pub fn subtract(&mut self, key: &K, value: V) {
105 let env = self.env_for_key(key);
106 let mut var = Var::<V>::instance(Rc::new(env), self.index);
107 var.subtract(value);
108 }
109}