Skip to main content

luct_store/
lib.rs

1//! Collection of implementations of different [`Stores`](luct_core::store::Store)
2#![forbid(unsafe_code)]
3
4// TODO: Move browser store into this crate
5
6mod file;
7mod last;
8mod lru;
9mod switch;
10
11pub use file::FilesystemStore;
12pub use last::LastValCacheStore;
13pub use lru::LruCacheStore;
14use luct_core::{
15    Fingerprint,
16    v1::{SignedCertificateTimestamp, SignedTreeHead},
17};
18pub use switch::StoreSwitch;
19
20/// Indicates, that a key can be serialized as a [`String`].
21///
22/// Some [`Store`](luct_core::store::Store) implementations need to internally store keys
23/// as a [`String`].
24///
25/// These implementations need to restrict their key type to [`StringStoreKey`].
26///
27/// # Caution
28/// In the case of [`StringStoreKey`], it is important that the [`String`] representation of the key
29/// has the same ordering as the actual keys.
30/// This is relevant for [`OrderedStores`](luct_core::store::OrderedStore).
31pub trait StringStoreKey: Clone + Ord + Send + 'static {
32    fn serialize_key(&self) -> String;
33    fn deserialize_key(key: &str) -> Option<Self>;
34}
35
36/// Indicates, that a value can be serialized as a [`String`].
37///
38/// Some [`Store`](luct_core::store::Store) implementations need to internally store values
39/// as a [`String`].
40///
41/// These implementations need to restrict their value type to [`StringStoreValue`].
42pub trait StringStoreValue: Clone + Send + Eq + 'static {
43    fn serialize_value(&self) -> String;
44    fn deserialize_value(value: &str) -> Option<Self>;
45}
46
47impl StringStoreKey for u64 {
48    fn serialize_key(&self) -> String {
49        self.to_string()
50    }
51
52    fn deserialize_key(key: &str) -> Option<Self> {
53        key.parse().ok()
54    }
55}
56
57impl StringStoreKey for Vec<u8> {
58    fn serialize_key(&self) -> String {
59        hex::encode(self)
60    }
61
62    fn deserialize_key(key: &str) -> Option<Self> {
63        hex::decode(key).ok()
64    }
65}
66
67impl StringStoreKey for [u8; 32] {
68    fn serialize_key(&self) -> String {
69        hex::encode(self)
70    }
71
72    fn deserialize_key(key: &str) -> Option<Self> {
73        hex::decode(key)
74            .map(|val| val.try_into().ok())
75            .ok()
76            .flatten()
77    }
78}
79
80impl StringStoreKey for Fingerprint {
81    fn serialize_key(&self) -> String {
82        self.0.serialize_key()
83    }
84
85    fn deserialize_key(key: &str) -> Option<Self> {
86        <[u8; 32]>::deserialize_key(key).map(Fingerprint)
87    }
88}
89
90impl StringStoreValue for () {
91    fn serialize_value(&self) -> String {
92        String::new()
93    }
94
95    fn deserialize_value(value: &str) -> Option<Self> {
96        match value {
97            "" => Some(()),
98            _ => None,
99        }
100    }
101}
102
103impl StringStoreValue for String {
104    fn serialize_value(&self) -> String {
105        self.clone()
106    }
107
108    fn deserialize_value(value: &str) -> Option<Self> {
109        Some(value.to_string())
110    }
111}
112
113impl StringStoreValue for SignedTreeHead {
114    fn serialize_value(&self) -> String {
115        serde_json::to_string(self).unwrap()
116    }
117
118    fn deserialize_value(value: &str) -> Option<Self> {
119        serde_json::from_str(value).ok()
120    }
121}
122
123impl StringStoreValue for SignedCertificateTimestamp {
124    fn serialize_value(&self) -> String {
125        serde_json::to_string(self).unwrap()
126    }
127
128    fn deserialize_value(value: &str) -> Option<Self> {
129        serde_json::from_str(value).ok()
130    }
131}
132
133// TODO: Implement RedbStore