jscpd_rs/detector/
store.rs1use std::{collections::HashMap, error::Error, fmt};
2
3#[derive(Clone, Debug, Eq, PartialEq)]
5pub struct MemoryStoreError {
6 namespace: String,
7 key: String,
8}
9
10impl MemoryStoreError {
11 pub fn new(namespace: impl Into<String>, key: impl Into<String>) -> Self {
13 Self {
14 namespace: namespace.into(),
15 key: key.into(),
16 }
17 }
18
19 pub fn namespace(&self) -> &str {
21 &self.namespace
22 }
23
24 pub fn key(&self) -> &str {
26 &self.key
27 }
28}
29
30impl fmt::Display for MemoryStoreError {
31 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(
33 formatter,
34 "key '{}' not found in namespace '{}'",
35 self.key, self.namespace
36 )
37 }
38}
39
40impl Error for MemoryStoreError {}
41
42#[derive(Clone, Debug)]
44pub struct MemoryStore<T> {
45 namespace: String,
46 values: HashMap<String, HashMap<String, T>>,
47}
48
49impl<T> Default for MemoryStore<T> {
50 fn default() -> Self {
51 Self::new()
52 }
53}
54
55impl<T> MemoryStore<T> {
56 pub fn new() -> Self {
58 Self {
59 namespace: String::new(),
60 values: HashMap::new(),
61 }
62 }
63
64 pub fn namespace(&mut self, namespace: impl Into<String>) {
66 self.namespace = namespace.into();
67 self.values.entry(self.namespace.clone()).or_default();
68 }
69
70 pub fn current_namespace(&self) -> &str {
72 &self.namespace
73 }
74
75 pub fn get(&self, key: impl AsRef<str>) -> Result<&T, MemoryStoreError> {
77 let key = key.as_ref();
78 self.values
79 .get(&self.namespace)
80 .and_then(|namespace| namespace.get(key))
81 .ok_or_else(|| MemoryStoreError::new(self.namespace.clone(), key))
82 }
83
84 pub fn set(&mut self, key: impl Into<String>, value: T) -> &T {
86 let key = key.into();
87 self.values
88 .entry(self.namespace.clone())
89 .or_default()
90 .entry(key)
91 .insert_entry(value)
92 .into_mut()
93 }
94
95 pub fn close(&mut self) {
97 self.values.clear();
98 }
99
100 pub fn is_empty(&self) -> bool {
102 self.values.values().all(HashMap::is_empty)
103 }
104
105 pub fn len(&self) -> usize {
107 self.values.values().map(HashMap::len).sum()
108 }
109}