Skip to main content

luct_store/
lib.rs

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