1use codec::keyvalue::*;
7use codec::{deserialize, serialize};
8use wapc_guest::host_call;
9use wascc_codec as codec;
10
11use crate::HandlerResult;
12
13const CAPID_KEYVALUE: &str = "wascc:keyvalue";
14
15pub struct KeyValueStoreHostBinding {
17 binding: String,
18}
19
20impl Default for KeyValueStoreHostBinding {
21 fn default() -> Self {
22 KeyValueStoreHostBinding {
23 binding: "default".to_string(),
24 }
25 }
26}
27
28pub fn host(binding: &str) -> KeyValueStoreHostBinding {
30 KeyValueStoreHostBinding {
31 binding: binding.to_string(),
32 }
33}
34
35pub fn default() -> KeyValueStoreHostBinding {
37 KeyValueStoreHostBinding::default()
38}
39
40impl KeyValueStoreHostBinding {
41 pub fn get(&self, key: &str) -> HandlerResult<Option<String>> {
43 let cmd = GetRequest {
44 key: key.to_string(),
45 };
46 host_call(&self.binding, CAPID_KEYVALUE, OP_GET, &serialize(cmd)?)
47 .map(|vec| {
48 let resp = deserialize::<GetResponse>(vec.as_ref()).unwrap();
49 if resp.exists {
50 Some(resp.value)
51 } else {
52 None
53 }
54 })
55 .map_err(|e| e.into())
56 }
57
58 pub fn set(&self, key: &str, value: &str, expires: Option<u32>) -> HandlerResult<()> {
60 let cmd = SetRequest {
61 key: key.to_string(),
62 value: value.to_string(),
63 expires_s: expires.unwrap_or(0) as _,
64 };
65 host_call(&self.binding, CAPID_KEYVALUE, OP_SET, &serialize(cmd)?)
66 .map(|_vec| ())
67 .map_err(|e| e.into())
68 }
69
70 pub fn atomic_add(&self, key: &str, value: i32) -> HandlerResult<i32> {
72 let cmd = AddRequest {
73 key: key.to_string(),
74 value,
75 };
76 host_call(&self.binding, CAPID_KEYVALUE, OP_ADD, &serialize(cmd)?)
77 .map(|vec| {
78 let resp = deserialize::<AddResponse>(vec.as_ref()).unwrap();
79 resp.value
80 })
81 .map_err(|e| e.into())
82 }
83
84 pub fn list_add(&self, key: &str, item: &str) -> HandlerResult<usize> {
86 let cmd = ListPushRequest {
87 key: key.to_string(),
88 value: item.to_string(),
89 };
90 host_call(&self.binding, CAPID_KEYVALUE, OP_PUSH, &serialize(cmd)?)
91 .map(|vec| {
92 let resp = deserialize::<ListResponse>(vec.as_ref()).unwrap();
93 resp.new_count as usize
94 })
95 .map_err(|e| e.into())
96 }
97
98 pub fn list_del_item(&self, key: &str, item: &str) -> HandlerResult<usize> {
100 let cmd = ListDelItemRequest {
101 key: key.to_string(),
102 value: item.to_string(),
103 };
104 host_call(&self.binding, CAPID_KEYVALUE, OP_LIST_DEL, &serialize(cmd)?)
105 .map(|vec| {
106 let resp = deserialize::<ListResponse>(vec.as_ref()).unwrap();
107 resp.new_count as usize
108 })
109 .map_err(|e| e.into())
110 }
111
112 pub fn del_key(&self, key: &str) -> HandlerResult<()> {
114 let cmd = DelRequest {
115 key: key.to_string(),
116 };
117 host_call(&self.binding, CAPID_KEYVALUE, OP_DEL, &serialize(cmd)?)
118 .map(|_vec| ())
119 .map_err(|e| e.into())
120 }
121
122 pub fn list_range(
124 &self,
125 key: &str,
126 start: isize,
127 stop_inclusive: isize,
128 ) -> HandlerResult<Vec<String>> {
129 let cmd = ListRangeRequest {
130 key: key.to_string(),
131 start: start as i32,
132 stop: stop_inclusive as i32,
133 };
134 host_call(&self.binding, CAPID_KEYVALUE, OP_RANGE, &serialize(cmd)?)
135 .map(|vec| {
136 let resp = deserialize::<ListRangeResponse>(vec.as_ref()).unwrap();
137 resp.values
138 })
139 .map_err(|e| e.into())
140 }
141
142 pub fn list_clear(&self, key: &str) -> HandlerResult<()> {
144 let cmd = ListClearRequest {
145 key: key.to_string(),
146 };
147 host_call(&self.binding, CAPID_KEYVALUE, OP_CLEAR, &serialize(cmd)?)
148 .map(|_vec| ())
149 .map_err(|e| e.into())
150 }
151
152 pub fn set_add(&self, key: &str, value: &str) -> HandlerResult<usize> {
154 let cmd = SetAddRequest {
155 key: key.to_string(),
156 value: value.to_string(),
157 };
158 host_call(&self.binding, CAPID_KEYVALUE, OP_SET_ADD, &serialize(cmd)?)
159 .map(|vec| {
160 let resp = deserialize::<SetOperationResponse>(vec.as_ref()).unwrap();
161 resp.new_count as usize
162 })
163 .map_err(|e| e.into())
164 }
165
166 pub fn set_remove(&self, key: &str, value: &str) -> HandlerResult<usize> {
168 let cmd = SetRemoveRequest {
169 key: key.to_string(),
170 value: value.to_string(),
171 };
172 host_call(
173 &self.binding,
174 CAPID_KEYVALUE,
175 OP_SET_REMOVE,
176 &serialize(cmd)?,
177 )
178 .map(|vec| {
179 let resp = deserialize::<SetOperationResponse>(vec.as_ref()).unwrap();
180 resp.new_count as usize
181 })
182 .map_err(|e| e.into())
183 }
184
185 pub fn set_union(&self, keys: Vec<String>) -> HandlerResult<Vec<String>> {
187 let cmd = SetUnionRequest { keys };
188 host_call(
189 &self.binding,
190 CAPID_KEYVALUE,
191 OP_SET_UNION,
192 &serialize(cmd)?,
193 )
194 .map(|vec| {
195 let resp = deserialize::<SetQueryResponse>(vec.as_ref()).unwrap();
196 resp.values
197 })
198 .map_err(|e| e.into())
199 }
200
201 pub fn set_intersect(&self, keys: Vec<String>) -> HandlerResult<Vec<String>> {
203 let cmd = SetIntersectionRequest { keys };
204 host_call(
205 &self.binding,
206 CAPID_KEYVALUE,
207 OP_SET_INTERSECT,
208 &serialize(cmd)?,
209 )
210 .map(|vec| {
211 let resp = deserialize::<SetQueryResponse>(vec.as_ref()).unwrap();
212 resp.values
213 })
214 .map_err(|e| e.into())
215 }
216
217 pub fn set_members(&self, key: &str) -> HandlerResult<Vec<String>> {
219 let cmd = SetQueryRequest {
220 key: key.to_string(),
221 };
222 host_call(
223 &self.binding,
224 CAPID_KEYVALUE,
225 OP_SET_QUERY,
226 &serialize(cmd)?,
227 )
228 .map(|vec| {
229 let resp = deserialize::<SetQueryResponse>(vec.as_ref()).unwrap();
230 resp.values
231 })
232 .map_err(|e| e.into())
233 }
234
235 pub fn exists(&self, key: &str) -> HandlerResult<bool> {
238 let cmd = KeyExistsQuery {
239 key: key.to_string(),
240 };
241 host_call(
242 &self.binding,
243 CAPID_KEYVALUE,
244 OP_KEY_EXISTS,
245 &serialize(cmd)?,
246 )
247 .map(|vec| {
248 let resp = deserialize::<GetResponse>(vec.as_ref()).unwrap();
249 resp.exists
250 })
251 .map_err(|e| e.into())
252 }
253}