1use crate::{error::RuntimeError, CallResult};
9use codec::Decode;
10
11#[link(wasm_import_module = "env")]
12extern "C" {
13 fn storage_put(
14 key_ptr: *const u8,
15 key_len: i32,
16 value_ptr: *const u8,
17 value_len: i32,
18 return_ptr: *mut u8,
19 ) -> i32;
20
21 fn storage_del(key_ptr: *const u8, key_len: i32, return_ptr: *mut u8) -> i32;
22
23 fn storage_get(k_ptr: *const u8, k_len: i32, return_ptr: *mut u8, v_offset: i32) -> i32;
24
25 fn storage_get_prefix(
26 k_ptr: *const u8,
27 k_len: i32,
28 direction: i32,
29 return_ptr: *mut u8,
30 v_offset: i32,
31 ) -> i32;
32
33 fn storage_get_range(
34 k_ptr: *const u8,
35 k_len: i32,
36 direction: i32,
37 limit: i32,
38 return_ptr: *mut u8,
39 v_offset: i32,
40 ) -> i32;
41
42 fn storage_del_range(
43 s0_ptr: *const u8,
44 s0_len: i32,
45 s1_ptr: *const u8,
46 s1_len: i32,
47 return_ptr: *mut u8,
48 ) -> i32;
49}
50
51pub fn put(key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) -> CallResult<()> {
53 let key = key.as_ref();
54 let value = value.as_ref();
55 assert!(key.len() <= i32::MAX as usize);
56 assert!(value.len() <= i32::MAX as usize);
57 let mut buf = crate::allocate_buffer();
58 let status = unsafe {
59 storage_put(
60 key.as_ptr(),
61 key.len() as i32,
62 value.as_ptr(),
63 value.len() as i32,
64 buf.as_mut_ptr(),
65 )
66 };
67 assert!(status == crate::NO_MORE_DATA);
68 CallResult::<()>::decode(&mut &buf[..]).map_err(|_| RuntimeError::DecodeReturnValueError)?
69}
70
71pub fn del(key: impl AsRef<[u8]>) -> CallResult<()> {
73 let key = key.as_ref();
74 assert!(key.len() <= i32::MAX as usize);
75 let mut buf = crate::allocate_buffer();
76 let status = unsafe { storage_del(key.as_ptr(), key.len() as i32, buf.as_mut_ptr()) };
77 assert!(status == crate::NO_MORE_DATA);
78 CallResult::<()>::decode(&mut &buf[..]).map_err(|_| RuntimeError::DecodeReturnValueError)?
79}
80
81pub fn get(key: impl AsRef<[u8]>) -> CallResult<Option<Vec<u8>>> {
83 let key = key.as_ref();
84 assert!(key.len() <= i32::MAX as usize);
85 let mut buf = crate::allocate_buffer();
86 let mut val = vec![];
87 loop {
88 let status = unsafe {
89 storage_get(
90 key.as_ptr(),
91 key.len() as i32,
92 buf.as_mut_ptr(),
93 val.len() as i32,
94 )
95 };
96 val.extend_from_slice(&buf);
97 if status == crate::NO_MORE_DATA {
98 break;
99 }
100 }
101 CallResult::<Option<Vec<u8>>>::decode(&mut &val[..])
102 .map_err(|_| RuntimeError::DecodeReturnValueError)?
103}
104
105#[derive(Clone, Copy, Debug, Eq, PartialEq)]
107pub enum Direction {
108 Forward,
109 Reverse,
110}
111
112impl Into<i32> for Direction {
113 fn into(self) -> i32 {
114 match self {
115 Direction::Forward => 0,
116 Direction::Reverse => 1,
117 }
118 }
119}
120
121impl From<i32> for Direction {
122 fn from(v: i32) -> Self {
123 match v {
124 0 => Direction::Forward,
125 1 => Direction::Reverse,
126 _ => unreachable!(),
127 }
128 }
129}
130
131pub fn get_range(
133 start_key: impl AsRef<[u8]>,
134 direction: Direction,
135 limit: usize,
136) -> CallResult<Vec<(Vec<u8>, Vec<u8>)>> {
137 let start = start_key.as_ref();
138 assert!(start.len() <= i32::MAX as usize);
139 assert!(limit <= 1000);
140 let mut buf = crate::allocate_buffer();
141 let mut val = vec![];
142 loop {
143 let status = unsafe {
144 storage_get_range(
145 start.as_ptr(),
146 start.len() as i32,
147 direction.into(),
148 limit as i32,
149 buf.as_mut_ptr(),
150 val.len() as i32,
151 )
152 };
153 val.extend_from_slice(&buf);
154 if status == crate::NO_MORE_DATA {
155 break;
156 }
157 }
158 CallResult::<Vec<(Vec<u8>, Vec<u8>)>>::decode(&mut &val[..])
159 .map_err(|_| RuntimeError::DecodeReturnValueError)?
160}
161
162pub fn search(
179 key_prefix: impl AsRef<[u8]>,
180 direction: Direction,
181) -> CallResult<Option<(Vec<u8>, Vec<u8>)>> {
182 let key = key_prefix.as_ref();
183 assert!(key.len() <= i32::MAX as usize);
184 let mut buf = crate::allocate_buffer();
185 let mut val = vec![];
186 loop {
187 let status = unsafe {
188 storage_get_prefix(
189 key.as_ptr(),
190 key.len() as i32,
191 direction.into(),
192 buf.as_mut_ptr(),
193 val.len() as i32,
194 )
195 };
196 val.extend_from_slice(&buf);
197 if status == crate::NO_MORE_DATA {
198 break;
199 }
200 }
201 CallResult::<Option<(Vec<u8>, Vec<u8>)>>::decode(&mut &val[..])
202 .map_err(|_| RuntimeError::DecodeReturnValueError)?
203}
204
205pub fn delete_range(start_key: impl AsRef<[u8]>, end_key: impl AsRef<[u8]>) -> CallResult<()> {
207 let start = start_key.as_ref();
208 let end = end_key.as_ref();
209 assert!(start.len() <= i32::MAX as usize);
210 assert!(end.len() <= i32::MAX as usize);
211 let mut buf = crate::allocate_buffer();
212 let status = unsafe {
213 storage_del_range(
214 start.as_ptr(),
215 start.len() as i32,
216 end.as_ptr(),
217 end.len() as i32,
218 buf.as_mut_ptr(),
219 )
220 };
221 assert!(status == crate::NO_MORE_DATA);
222 CallResult::<()>::decode(&mut &buf[..]).map_err(|_| RuntimeError::DecodeReturnValueError)?
223}