transaction_processor/
account.rs

1use sys;
2use types::*;
3
4pub struct Account<'a> {
5    key: Option<&'a str>,
6}
7
8impl<'a> Account<'a> {
9    pub fn sender() -> Account<'static> {
10        Account { key: None }
11    }
12
13    pub fn sender_id() -> String {
14        let mut buf: Vec<u8> = Vec::with_capacity(128);
15        unsafe {
16            buf.set_len(128);
17            let copied = ::sys::_sender_id(buf.as_mut_ptr(), buf.len());
18            buf.set_len(copied);
19        }
20        String::from_utf8(buf).unwrap()
21    }
22
23    pub fn load(key: &'a str) -> Account<'a> {
24        Account { key: Some(key) }
25    }
26
27    fn load_current(&self) -> ProcessResult<()> {
28        match self.key {
29            Some(key) => {
30                if unsafe { sys::_load_account(key.as_ptr(), key.len()) }
31                    != InternalProcessResult::Ok
32                {
33                    Err(ProcessError::NotFound)
34                } else {
35                    Ok(())
36                }
37            }
38            None => {
39                unsafe { sys::_load_sender() };
40                Ok(())
41            }
42        }
43    }
44
45    pub fn get(&self, key: &str) -> ProcessResult<Vec<u8>> {
46        self.load_current()?;
47        let key = key.as_bytes();
48
49        let value_len = unsafe { sys::_load_len(StoreId::Account, key.as_ptr(), key.len()) };
50        if value_len == 0 {
51            return Err(ProcessError::NotFound);
52        }
53
54        let mut ret: Vec<u8> = Vec::with_capacity(value_len);
55        unsafe { ret.set_len(value_len) };
56        unsafe { sys::_load(StoreId::Account, key.as_ptr(), key.len(), ret.as_mut_ptr()) };
57
58        Ok(ret)
59    }
60
61    pub fn get_string(&self, key: &str) -> ProcessResult<String> {
62        self.get(key)
63            .and_then(|v| String::from_utf8(v).map_err(|_| ProcessError::InvalidData))
64    }
65
66    pub fn get_u64(&self, key: &str) -> ProcessResult<u64> {
67        self.get(key).and_then(|v| {
68            if v.len() == 8 {
69                Ok(unsafe { *(v.as_ptr() as *const u64) })
70            } else {
71                Err(ProcessError::InvalidData)
72            }
73        })
74    }
75
76    pub fn set(&self, key: &str, value: &[u8]) -> ProcessResult<()> {
77        self.load_current()?;
78        let key = key.as_bytes();
79
80        unsafe {
81            sys::_store(
82                StoreId::Account,
83                key.as_ptr(),
84                key.len(),
85                value.as_ptr(),
86                value.len(),
87            )
88        }.into()
89    }
90
91    pub fn set_string(&self, key: &str, value: &str) -> ProcessResult<()> {
92        self.set(key, value.as_bytes())
93    }
94
95    pub fn set_u64(&self, key: &str, value: u64) -> ProcessResult<()> {
96        self.set(key, &unsafe {
97            ::std::mem::transmute::<u64, [u8; 8]>(value)
98        })
99    }
100}