samod_core/
storage_key.rs1use std::fmt;
2
3use automerge::ChangeHash;
4
5use crate::{CompactionHash, DocumentId};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub struct StorageKey(Vec<String>);
35
36impl StorageKey {
37 pub fn storage_id_path() -> StorageKey {
38 StorageKey(vec!["storage-adapter-id".to_string()])
39 }
40
41 pub fn incremental_path(doc_id: &DocumentId, change_hash: ChangeHash) -> StorageKey {
42 StorageKey(vec![
43 doc_id.to_string(),
44 "incremental".to_string(),
45 change_hash.to_string(),
46 ])
47 }
48
49 pub fn snapshot_path(doc_id: &DocumentId, compaction_hash: &CompactionHash) -> StorageKey {
50 StorageKey(vec![
51 doc_id.to_string(),
52 "snapshot".to_string(),
53 compaction_hash.to_string(),
54 ])
55 }
56
57 pub fn from_parts(parts: &[&str]) -> Self {
71 StorageKey(parts.iter().map(|s| s.to_string()).collect())
72 }
73
74 pub fn is_prefix_of(&self, other: &StorageKey) -> bool {
80 if self.0.len() > other.0.len() {
81 return false;
82 }
83 self.0.iter().zip(other.0.iter()).all(|(a, b)| a == b)
84 }
85
86 pub fn onelevel_deeper(&self, prefix: &StorageKey) -> Option<StorageKey> {
103 if prefix.is_prefix_of(self) && self.0.len() > prefix.0.len() {
104 let components = self.0.iter().take(prefix.0.len() + 1).cloned();
105 Some(StorageKey(components.collect()))
106 } else {
107 None
108 }
109 }
110
111 pub fn with_suffix(&self, suffix: StorageKey) -> StorageKey {
112 let mut new_key = self.0.clone();
113 new_key.extend(suffix.0);
114 StorageKey(new_key)
115 }
116
117 pub fn with_component(&self, component: String) -> StorageKey {
118 let mut new_key = self.0.clone();
119 new_key.push(component);
120 StorageKey(new_key)
121 }
122}
123
124impl IntoIterator for StorageKey {
125 type Item = String;
126 type IntoIter = std::vec::IntoIter<String>;
127
128 fn into_iter(self) -> Self::IntoIter {
129 self.0.into_iter()
130 }
131}
132
133impl<'a> IntoIterator for &'a StorageKey {
134 type Item = &'a String;
135 type IntoIter = std::slice::Iter<'a, String>;
136
137 fn into_iter(self) -> Self::IntoIter {
138 self.0.iter()
139 }
140}
141
142impl FromIterator<String> for StorageKey {
143 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
144 StorageKey(iter.into_iter().collect())
145 }
146}
147
148impl<'a> FromIterator<&'a str> for StorageKey {
149 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
150 StorageKey(iter.into_iter().map(String::from).collect())
151 }
152}
153
154impl<'a> From<Vec<&'a str>> for StorageKey {
155 fn from(vec: Vec<&'a str>) -> Self {
156 StorageKey(vec.into_iter().map(String::from).collect())
157 }
158}
159
160impl From<Vec<String>> for StorageKey {
161 fn from(vec: Vec<String>) -> Self {
162 StorageKey(vec)
163 }
164}
165
166impl fmt::Display for StorageKey {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 write!(f, "{}", self.0.join("/"))
169 }
170}