transaction_processor/
account.rs1use 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}