Skip to main content

somatize_core/
packing.rs

1//! A keeper with a codec in front of it.
2
3use crate::{Codec, Keeper, KeeperError, Kept, Key, Value};
4
5/// Whatever a [`Codec`] can write down, kept — by a [`Keeper`] that never finds
6/// out any of it was ever anything but bytes.
7///
8/// A store and a wire ask an opaque value the same question, so the pair
9/// `(keeper, codec)` is wired up once here rather than once per tenant. What is
10/// decided here is that the directions are **not** symmetrical: failing to
11/// *name* a value costs the name and the run goes on, while failing to keep it
12/// or to read it back is the keeper's error.
13pub struct Packing<'a> {
14    inner: &'a dyn Keeper,
15    codec: &'a dyn Codec,
16}
17
18impl<'a> Packing<'a> {
19    /// That keeper, with that codec in front of it.
20    pub fn over(inner: &'a dyn Keeper, codec: &'a dyn Codec) -> Self {
21        Self { inner, codec }
22    }
23}
24
25impl Keeper for Packing<'_> {
26    fn key_of(&self, value: &Value) -> Option<Key> {
27        self.inner.key_of(&self.codec.packed(value).ok()?)
28    }
29
30    fn combine(&self, parts: &[&str]) -> Key {
31        self.inner.combine(parts)
32    }
33
34    /// Straight through: whether something is kept is a question about names,
35    /// and a codec has nothing to say about a name.
36    fn present(&self, keys: &[&Key]) -> Result<Vec<bool>, KeeperError> {
37        self.inner.present(keys)
38    }
39
40    fn recall(&self, keys: &[&Key]) -> Result<Vec<Option<Kept>>, KeeperError> {
41        self.inner
42            .recall(keys)?
43            .into_iter()
44            .map(|kept| match kept {
45                None => Ok(None),
46                Some(kept) => Ok(Some(Kept {
47                    value: self
48                        .codec
49                        .unpacked(&kept.value)
50                        .map_err(|e| KeeperError::new(e.to_string()))?,
51                    meta: kept.meta,
52                })),
53            })
54            .collect()
55    }
56
57    fn keep(&self, key: &Key, value: &Value, meta: &[(&str, &str)]) -> Result<(), KeeperError> {
58        let written = self
59            .codec
60            .packed(value)
61            .map_err(|e| KeeperError::new(e.to_string()))?;
62        self.inner.keep(key, &written, meta)
63    }
64}