1use alloc::collections::BTreeMap;
4use alloc::string::String;
5use alloc::vec::Vec;
6
7use core::borrow::Borrow;
8use core::marker::PhantomData;
9
10use crate::{Codec, Postcard, Result, Sri};
11
12use crate::db::{Cursor, Scope, TbOrderBy, tb_append, tb_count, tb_delete, tb_get, tb_list};
13
14pub trait AsEid {
16 fn as_eid(&self) -> Vec<u8>;
18}
19
20pub trait TableKey: AsEid + Sized {
23 fn from_eid(eid: &[u8]) -> Self;
25}
26
27impl AsEid for str {
28 fn as_eid(&self) -> Vec<u8> {
29 self.as_bytes().to_vec()
30 }
31}
32
33impl AsEid for String {
34 fn as_eid(&self) -> Vec<u8> {
35 self.as_bytes().to_vec()
36 }
37}
38
39impl TableKey for String {
40 fn from_eid(eid: &[u8]) -> Self {
41 String::from_utf8_lossy(eid).into_owned()
42 }
43}
44
45impl AsEid for [u8] {
46 fn as_eid(&self) -> Vec<u8> {
47 self.to_vec()
48 }
49}
50
51impl AsEid for Vec<u8> {
52 fn as_eid(&self) -> Vec<u8> {
53 self.clone()
54 }
55}
56
57impl TableKey for Vec<u8> {
58 fn from_eid(eid: &[u8]) -> Self {
59 eid.to_vec()
60 }
61}
62
63impl AsEid for Sri {
64 fn as_eid(&self) -> Vec<u8> {
65 self.to_bytes().to_vec()
66 }
67}
68
69impl TableKey for Sri {
70 fn from_eid(eid: &[u8]) -> Self {
71 let mut bytes = [0u8; 16];
72 let n = eid.len().min(16);
73 bytes[..n].copy_from_slice(&eid[..n]);
74 Sri::from_bytes(bytes)
75 }
76}
77
78pub struct Table<V, K = String, C = Postcard> {
84 scope: Scope,
85 name: &'static str,
86 _marker: PhantomData<(V, K, C)>,
87}
88
89impl<V, K, C> Table<V, K, C> {
90 pub const fn new(name: &'static str) -> Self {
92 Self::new_in(name, Scope::private())
93 }
94
95 pub const fn new_in(name: &'static str, scope: Scope) -> Self {
97 Self {
98 scope,
99 name,
100 _marker: PhantomData,
101 }
102 }
103
104 fn scope(&self) -> Scope {
105 self.scope.clone()
106 }
107}
108
109impl<V, K, C> Table<V, K, C>
110where
111 V: serde::Serialize + serde::de::DeserializeOwned,
112 C: Codec,
113{
114 pub fn get<Q>(&self, key: &Q) -> Result<Option<V>>
116 where
117 K: Borrow<Q>,
118 Q: AsEid + ?Sized,
119 {
120 let mut req = [0u8; 256];
121 let mut resp = alloc::vec![0u8; 4096];
122 tb_get(
123 self.scope(),
124 String::from(self.name),
125 key.as_eid(),
126 &mut req,
127 &mut resp,
128 )?
129 .map(|b| C::decode(&b))
130 .transpose()
131 }
132
133 pub fn insert(&self, val: &V) -> Result<()> {
135 self.insert_impl(None, C::encode(val)?)
136 }
137
138 pub fn insert_with<Q>(&self, key: &Q, val: &V) -> Result<()>
140 where
141 K: Borrow<Q>,
142 Q: AsEid + ?Sized,
143 {
144 self.insert_impl(Some(key.as_eid()), C::encode(val)?)
145 }
146
147 fn insert_impl(&self, key: Option<Vec<u8>>, val: Vec<u8>) -> Result<()> {
151 let mut req = alloc::vec![0u8; val.len() + 1024];
152 tb_append(self.scope(), String::from(self.name), key, val, &mut req)
153 .map_err(|_| "Table::insert")?;
154 Ok(())
155 }
156
157 pub fn delete<Q>(&self, key: &Q) -> Result<()>
159 where
160 K: Borrow<Q>,
161 Q: AsEid + ?Sized,
162 {
163 let mut buf = [0u8; 256];
164 tb_delete(
165 self.scope(),
166 String::from(self.name),
167 key.as_eid(),
168 &mut buf,
169 )
170 .map_err(|_| "Table::delete")?;
171 Ok(())
172 }
173
174 pub fn count(&self) -> Result<usize> {
176 let mut req = [0u8; 256];
177 let mut resp = [0u8; 64];
178 tb_count(self.scope(), String::from(self.name), &mut req, &mut resp)
179 .map_err(|_| "Table::count")
180 }
181
182 pub fn list(&self) -> Result<Vec<V>> {
184 let mut out = Vec::new();
185 self.for_each(|v| out.push(v))?;
186 Ok(out)
187 }
188
189 pub fn list_rev(&self) -> Result<Vec<V>> {
191 let mut out = Vec::new();
192 self.for_each_rev(|v| out.push(v))?;
193 Ok(out)
194 }
195
196 pub fn for_each<F: FnMut(V)>(&self, mut f: F) -> Result<()> {
198 let scope = self.scope();
199 for_each_ordered::<_, V, C>(&scope, self.name, TbOrderBy::KeyAsc, |_eid, val: V| f(val))
200 }
201
202 pub fn for_each_rev<F: FnMut(V)>(&self, mut f: F) -> Result<()> {
204 let scope = self.scope();
205 for_each_ordered::<_, V, C>(&scope, self.name, TbOrderBy::KeyDesc, |_eid, val: V| f(val))
206 }
207
208 fn iter_raw(&self, order: TbOrderBy) -> IterRaw {
210 IterRaw::new(self.scope(), String::from(self.name), order)
211 }
212
213 pub fn iter(&self) -> Iter<V, K, C> {
215 Iter {
216 raw: self.iter_raw(TbOrderBy::KeyAsc),
217 _marker: PhantomData,
218 }
219 }
220
221 pub fn iter_rev(&self) -> Iter<V, K, C> {
223 Iter {
224 raw: self.iter_raw(TbOrderBy::KeyDesc),
225 _marker: PhantomData,
226 }
227 }
228
229 pub fn keys(&self) -> Keys<K> {
231 Keys {
232 raw: self.iter_raw(TbOrderBy::KeyAsc),
233 _marker: PhantomData,
234 }
235 }
236
237 pub fn keys_rev(&self) -> Keys<K> {
239 Keys {
240 raw: self.iter_raw(TbOrderBy::KeyDesc),
241 _marker: PhantomData,
242 }
243 }
244
245 pub fn ids(&self) -> Result<Vec<K>>
247 where
248 K: TableKey,
249 {
250 self.keys().collect()
251 }
252
253 pub fn to_map(&self) -> Result<BTreeMap<K, V>>
257 where
258 K: TableKey + Ord,
259 {
260 self.iter().collect()
261 }
262}
263
264struct IterRaw {
267 scope: Scope,
268 table: String,
269 cursor: Option<Cursor>,
270 order: TbOrderBy,
271 done: bool,
272}
273
274impl IterRaw {
275 fn new(scope: Scope, table: String, order: TbOrderBy) -> Self {
276 Self {
277 scope,
278 table,
279 cursor: None,
280 order,
281 done: false,
282 }
283 }
284}
285
286impl Iterator for IterRaw {
287 type Item = Result<(Vec<u8>, Vec<u8>)>;
288
289 fn next(&mut self) -> Option<Self::Item> {
290 if self.done {
291 return None;
292 }
293 let mut req = [0u8; 256];
294 let mut resp = alloc::vec![0u8; 4096];
295 let row = tb_list(
296 self.scope.clone(),
297 self.table.clone(),
298 self.cursor.take(),
299 Some(1),
300 Some(self.order),
301 &mut req,
302 &mut resp,
303 );
304
305 let rows = match row {
306 Ok(rows) => rows,
307 Err(_) => {
308 self.done = true;
309 return Some(Err("tb_list"));
310 }
311 };
312 let Some((eid, val)) = rows.into_iter().next() else {
313 self.done = true;
314 return None;
315 };
316 self.cursor = Some(Cursor::After(eid.clone()));
317 Some(Ok((eid, val)))
318 }
319}
320
321pub struct Iter<V, K, C = Postcard> {
323 raw: IterRaw,
324 _marker: PhantomData<(V, K, C)>,
325}
326
327impl<V, K, C> Iterator for Iter<V, K, C>
328where
329 V: serde::de::DeserializeOwned,
330 K: TableKey,
331 C: Codec,
332{
333 type Item = Result<(K, V)>;
334
335 fn next(&mut self) -> Option<Self::Item> {
336 let (eid, val) = match self.raw.next()? {
337 Ok(pair) => pair,
338 Err(e) => return Some(Err(e)),
339 };
340 Some(C::decode::<V>(&val).map(|v| (K::from_eid(&eid), v)))
341 }
342}
343
344pub struct Keys<K = String> {
346 raw: IterRaw,
347 _marker: PhantomData<K>,
348}
349
350impl<K> Iterator for Keys<K>
351where
352 K: TableKey,
353{
354 type Item = Result<K>;
355
356 fn next(&mut self) -> Option<Self::Item> {
357 match self.raw.next()? {
358 Ok((eid, _val)) => Some(Ok(K::from_eid(&eid))),
359 Err(e) => Some(Err(e)),
360 }
361 }
362}
363
364pub fn for_each<F, T>(scope: &Scope, table: &str, f: F) -> Result<()>
368where
369 F: for<'a> FnMut(&'a [u8], T),
370 T: serde::de::DeserializeOwned,
371{
372 for_each_ordered::<_, T, Postcard>(scope, table, TbOrderBy::KeyAsc, f)
373}
374
375fn for_each_ordered<F, T, C>(scope: &Scope, table: &str, order: TbOrderBy, mut f: F) -> Result<()>
376where
377 F: for<'a> FnMut(&'a [u8], T),
378 T: serde::de::DeserializeOwned,
379 C: Codec,
380{
381 for_each_raw_ordered(scope, table, order, |eid, val| {
382 if let Ok(s) = C::decode::<T>(&val) {
383 f(eid, s);
384 }
385 })
386}
387
388pub fn for_each_raw<F>(scope: &Scope, table: &str, f: F) -> Result<()>
391where
392 F: for<'a> FnMut(&'a [u8], Vec<u8>),
393{
394 for_each_raw_ordered(scope, table, TbOrderBy::KeyAsc, f)
395}
396
397fn for_each_raw_ordered<F>(scope: &Scope, table: &str, order: TbOrderBy, mut f: F) -> Result<()>
398where
399 F: for<'a> FnMut(&'a [u8], Vec<u8>),
400{
401 for row in IterRaw::new(scope.clone(), String::from(table), order) {
402 let (eid, val) = row?;
403 f(eid.as_slice(), val);
404 }
405 Ok(())
406}