Skip to main content

detsys_ids_client/storage/
mod.rs

1mod generic;
2mod json_file;
3
4pub use generic::Generic;
5pub use json_file::JsonFile;
6
7use crate::checkin::Checkin;
8use crate::identity::AnonymousDistinctId;
9use crate::{DeviceId, DistinctId, Groups};
10
11#[derive(Default, Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
12pub struct StoredProperties {
13    pub anonymous_distinct_id: AnonymousDistinctId,
14    pub distinct_id: Option<DistinctId>,
15    pub device_id: DeviceId,
16    #[serde(default)]
17    pub groups: Groups,
18    #[serde(default)]
19    pub checkin: Checkin,
20}
21
22pub trait Storage: Send + Sync + 'static {
23    type Error: std::fmt::Debug + std::fmt::Display;
24
25    fn load(
26        &self,
27    ) -> impl std::future::Future<Output = Result<Option<StoredProperties>, Self::Error>> + Send;
28    fn store(
29        &mut self,
30        properties: StoredProperties,
31    ) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send;
32}
33
34pub enum DefaultStorageChain {
35    JsonFile(JsonFile),
36    Generic(Generic),
37}
38
39#[derive(thiserror::Error, Debug)]
40pub enum DefaultStorageChainError {
41    #[error(transparent)]
42    JsonFile(#[from] <JsonFile as Storage>::Error),
43
44    #[error(transparent)]
45    Generic(#[from] <Generic as Storage>::Error),
46}
47
48impl DefaultStorageChain {
49    pub async fn new() -> DefaultStorageChain {
50        match JsonFile::try_default().await {
51            Ok(json) => Self::JsonFile(json),
52            Err(e) => {
53                tracing::debug!(
54                    ?e,
55                    "Failed to construct the default JsonFile storage, falling back to in-memory"
56                );
57                Self::Generic(Generic::default())
58            }
59        }
60    }
61}
62
63impl Storage for DefaultStorageChain {
64    type Error = DefaultStorageChainError;
65
66    async fn load(&self) -> Result<Option<StoredProperties>, Self::Error> {
67        match self {
68            DefaultStorageChain::JsonFile(json_file) => Ok(json_file.load().await?),
69            DefaultStorageChain::Generic(generic) => Ok(generic.load().await?),
70        }
71    }
72
73    async fn store(&mut self, properties: StoredProperties) -> Result<(), Self::Error> {
74        match self {
75            DefaultStorageChain::JsonFile(json_file) => Ok(json_file.store(properties).await?),
76            DefaultStorageChain::Generic(generic) => Ok(generic.store(properties).await?),
77        }
78    }
79}