launchdarkly_server_sdk/stores/
persistent_store.rs1use core::fmt;
2use std::collections::HashMap;
3
4use super::store_types::{AllData, DataKind, SerializedItem};
5
6#[derive(Debug)]
8pub struct PersistentStoreError {
9 message: String,
10}
11
12impl PersistentStoreError {
13 pub fn new(message: impl Into<String>) -> Self {
15 Self {
16 message: message.into(),
17 }
18 }
19}
20
21impl std::error::Error for PersistentStoreError {
22 fn description(&self) -> &str {
23 &self.message
24 }
25}
26
27impl fmt::Display for PersistentStoreError {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(f, "{}", self.message)
30 }
31}
32
33pub trait PersistentDataStore: Send + Sync {
41 fn init(
49 &mut self,
50 all_data: AllData<SerializedItem, SerializedItem>,
51 ) -> Result<(), PersistentStoreError>;
52
53 fn flag(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError>;
60
61 fn segment(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError>;
68
69 fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError>;
74
75 fn upsert(
82 &mut self,
83 kind: DataKind,
84 key: &str,
85 serialized_item: SerializedItem,
86 ) -> Result<bool, PersistentStoreError>;
87
88 fn is_initialized(&self) -> bool;
94}
95
96#[cfg(test)]
97pub(crate) mod tests {
98 use crate::stores::persistent_store::PersistentDataStore;
99 use crate::stores::store_types::{AllData, DataKind, SerializedItem};
100 use std::collections::HashMap;
101
102 use super::PersistentStoreError;
103
104 pub struct NullPersistentDataStore {
105 pub(crate) initialized: bool,
106 }
107
108 impl PersistentDataStore for NullPersistentDataStore {
109 fn init(
110 &mut self,
111 _all_data: AllData<SerializedItem, SerializedItem>,
112 ) -> Result<(), PersistentStoreError> {
113 self.initialized = true;
114 Ok(())
115 }
116
117 fn flag(&self, _key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
118 Ok(None)
119 }
120
121 fn segment(&self, _key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
122 Ok(None)
123 }
124
125 fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError> {
126 Ok(HashMap::new())
127 }
128
129 fn upsert(
130 &mut self,
131 _kind: DataKind,
132 _key: &str,
133 _serialized_item: SerializedItem,
134 ) -> Result<bool, PersistentStoreError> {
135 Ok(true)
136 }
137
138 fn is_initialized(&self) -> bool {
139 self.initialized
140 }
141 }
142
143 pub struct InMemoryPersistentDataStore {
144 pub(crate) data: AllData<SerializedItem, SerializedItem>,
145 pub(crate) initialized: bool,
146 }
147
148 impl PersistentDataStore for InMemoryPersistentDataStore {
149 fn init(
150 &mut self,
151 all_data: AllData<SerializedItem, SerializedItem>,
152 ) -> Result<(), PersistentStoreError> {
153 self.data = all_data;
154 self.initialized = true;
155 Ok(())
156 }
157
158 fn flag(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
159 Ok(self.data.flags.get(key).map(|value| (*value).clone()))
160 }
161
162 fn segment(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
163 Ok(self.data.segments.get(key).map(|value| (*value).clone()))
164 }
165
166 fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError> {
167 Ok(self.data.flags.clone())
168 }
169
170 fn upsert(
171 &mut self,
172 kind: DataKind,
173 key: &str,
174 serialized_item: SerializedItem,
175 ) -> Result<bool, PersistentStoreError> {
176 let original = match kind {
177 DataKind::Flag => self.data.flags.insert(key.to_string(), serialized_item),
178 DataKind::Segment => self.data.segments.insert(key.to_string(), serialized_item),
179 };
180
181 Ok(original.is_some())
182 }
183
184 fn is_initialized(&self) -> bool {
185 self.initialized
186 }
187 }
188}