1use std::{borrow::Cow, marker::PhantomData};
2
3use crate::{
4 Codec, DataStructure, Encoding, KeySerde, KeyType, Storage, StorageError, StorageMut, Terminal,
5};
6
7pub struct Item<'a, V: Codec<Enc>, Enc: Encoding, K: KeySerde = Cow<'a, [u8]>>(
8 KeyType<K>,
9 PhantomData<(&'a K, V, Enc)>,
10);
11
12impl<'a, V: Codec<Enc>, Enc: Encoding, K: KeySerde> DataStructure for Item<'a, V, Enc, K> {
13 type Key = K;
14 type Enc = Enc;
15 type Value = V;
16 type DsType = Terminal;
17
18 fn with_prefix(prefix: Vec<u8>) -> Self {
19 Self(KeyType::Raw(prefix), PhantomData)
20 }
21
22 fn should_skip_key(_: &Self::Key) -> bool {
23 false
24 }
25}
26
27impl<V: Codec<Enc>, Enc: Encoding> Item<'static, V, Enc> {
28 pub const fn new(key: &'static [u8]) -> Self {
29 Self(KeyType::Key(Cow::Borrowed(key)), PhantomData)
30 }
31}
32
33impl<'a, V: Codec<Enc>, Enc: Encoding, K: KeySerde> Item<'a, V, Enc, K> {
34 pub fn with_key(key: K) -> Self {
35 Self(KeyType::Key(key), PhantomData)
36 }
37
38 pub fn may_load<S: Storage>(&self, storage: &S) -> Result<Option<V>, StorageError<Enc>> {
39 let bytes = storage.get(&self.0)?;
40 let value = bytes.map(|b| V::decode(b.as_slice())).transpose();
41 value.map_err(StorageError::ValueDeserialize)
42 }
43
44 pub fn save<S: StorageMut>(&self, storage: &mut S, value: &V) -> Result<(), StorageError<Enc>> {
45 let key = self.0.encode()?;
46 let value = value.encode().map_err(StorageError::ValueSerialize)?;
47 storage.set_raw(key, value);
48 Ok(())
49 }
50
51 pub fn delete<S: StorageMut>(&self, storage: &mut S) -> Result<(), StorageError<Enc>> {
52 Ok(storage.delete(&self.0)?)
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use std::collections::HashMap;
59
60 use crate::mock::DisplayEncoding;
61
62 use super::*;
63
64 #[test]
65 fn test_item() {
66 const ITEM: Item<String, DisplayEncoding> = Item::new(b"foo");
67 let item: Item<String, DisplayEncoding> = Item::with_key(Cow::Owned(b"bar".to_vec()));
68
69 let mut storage: HashMap<Vec<u8>, Vec<u8>> = HashMap::new();
70 assert_eq!(ITEM.may_load(&storage), Ok(None));
71 assert_eq!(item.may_load(&storage), Ok(None));
72
73 ITEM.save(&mut storage, &"baz".to_string()).unwrap();
74 assert_eq!(ITEM.may_load(&storage), Ok(Some("baz".to_string())));
75 assert_eq!(item.may_load(&storage), Ok(None));
76
77 item.save(&mut storage, &"qux".to_string()).unwrap();
78 assert_eq!(ITEM.may_load(&storage), Ok(Some("baz".to_string())));
79 assert_eq!(item.may_load(&storage), Ok(Some("qux".to_string())));
80
81 item.delete(&mut storage).unwrap();
82 assert_eq!(ITEM.may_load(&storage), Ok(Some("baz".to_string())));
83 assert_eq!(item.may_load(&storage), Ok(None));
84 }
85}