redact_crypto/storage/
selfstore.rs1use crate::{CryptoError, Entry, NonIndexedTypeStorer, StorableType, Storer, TypeStorer};
2use async_trait::async_trait;
3use once_cell::sync::Lazy;
4use serde::{Deserialize, Serialize};
5use std::{
6 error::Error,
7 fmt::Display,
8 sync::{Arc, RwLock},
9};
10
11static SELF_STORER: Lazy<RwLock<Arc<SelfStorer>>> = Lazy::new(|| RwLock::new(Default::default()));
12
13#[derive(Debug)]
14pub enum SelfStorerError {
15 NoSelfStorerProvided,
17}
18
19impl Error for SelfStorerError {
20 fn source(&self) -> Option<&(dyn Error + 'static)> {
21 match *self {
22 SelfStorerError::NoSelfStorerProvided => None,
23 }
24 }
25}
26
27impl Display for SelfStorerError {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 match *self {
30 SelfStorerError::NoSelfStorerProvided => write!(f, "No self storer was defined"),
31 }
32 }
33}
34
35impl From<SelfStorerError> for CryptoError {
36 fn from(sse: SelfStorerError) -> Self {
37 match sse {
38 SelfStorerError::NoSelfStorerProvided => CryptoError::InternalError {
39 source: Box::new(sse),
40 },
41 }
42 }
43}
44
45#[derive(Serialize, Deserialize, Debug, Clone, Default)]
46pub struct SelfStorer {
47 #[serde(skip)]
48 internal_storer: Option<Box<TypeStorer>>,
49}
50
51impl From<SelfStorer> for NonIndexedTypeStorer {
52 fn from(ss: SelfStorer) -> Self {
53 NonIndexedTypeStorer::SelfStore(ss)
54 }
55}
56
57impl From<SelfStorer> for TypeStorer {
58 fn from(ss: SelfStorer) -> Self {
59 TypeStorer::NonIndexed(NonIndexedTypeStorer::SelfStore(ss))
60 }
61}
62
63impl SelfStorer {
64 pub fn current() -> Arc<SelfStorer> {
65 SELF_STORER.read().unwrap().clone()
66 }
67
68 pub fn make_current(self) {
69 *SELF_STORER.write().unwrap() = Arc::new(self)
70 }
71}
72
73#[async_trait]
74impl Storer for SelfStorer {
75 async fn get<T: StorableType>(&self, path: &str) -> Result<Entry<T>, CryptoError> {
76 match SelfStorer::current().internal_storer {
77 Some(ref storer) => storer.get(path).await,
78 None => Err(SelfStorerError::NoSelfStorerProvided.into()),
79 }
80 }
81
82 async fn create<T: StorableType>(&self, value: Entry<T>) -> Result<Entry<T>, CryptoError> {
83 match SelfStorer::current().internal_storer {
84 Some(ref storer) => storer.create(value).await,
85 None => Err(SelfStorerError::NoSelfStorerProvided.into()),
86 }
87 }
88}