link_cli/storage/
decorator_impls.rs1use doublets::data::LinkReference;
17
18use crate::error::LinkError;
19use crate::link::{GenericLink, Link};
20use crate::link_storage::LinkStorage;
21use crate::named_types::NamedTypesDecorator;
22use crate::pinned_types::PinnedTypesDecorator;
23use crate::storage::traits::{LinksStorage, LinksStorageRef, StorageRevision};
24
25fn storage_error(error: anyhow::Error) -> LinkError {
26 LinkError::StorageError(format!("{error:#}"))
27}
28
29macro_rules! impl_in_memory_links_storage {
33 ($type:ty, $create:expr, $flush:expr, $external:expr, $reload:expr) => {
34 impl LinksStorage<u32> for $type {
35 fn create_link(&mut self, source: u32, target: u32) -> Result<u32, LinkError> {
36 #[allow(clippy::redundant_closure_call)]
37 Ok($create(self, source, target))
38 }
39
40 fn ensure_link_created(&mut self, index: u32) -> Result<u32, LinkError> {
41 Ok(self.ensure_created(index))
42 }
43
44 fn get_link(&self, index: u32) -> Option<GenericLink<u32>> {
45 self.get(index).copied()
46 }
47
48 fn link_exists(&self, index: u32) -> bool {
49 self.exists(index)
50 }
51
52 fn update_link(
53 &mut self,
54 index: u32,
55 source: u32,
56 target: u32,
57 ) -> Result<GenericLink<u32>, LinkError> {
58 self.update(index, source, target).map_err(storage_error)
59 }
60
61 fn delete_link(&mut self, index: u32) -> Result<GenericLink<u32>, LinkError> {
62 self.delete(index).map_err(storage_error)
63 }
64
65 fn all_links(&self) -> Vec<GenericLink<u32>> {
66 self.all().into_iter().copied().collect()
67 }
68
69 fn query_links(
70 &self,
71 index: Option<u32>,
72 source: Option<u32>,
73 target: Option<u32>,
74 ) -> Vec<GenericLink<u32>> {
75 self.query(index, source, target)
76 .into_iter()
77 .copied()
78 .collect()
79 }
80
81 fn search_link(&self, source: u32, target: u32) -> Option<u32> {
82 self.search(source, target)
83 }
84
85 fn get_or_create_link(&mut self, source: u32, target: u32) -> Result<u32, LinkError> {
86 Ok(self.get_or_create(source, target))
87 }
88
89 fn flush(&mut self) -> Result<(), LinkError> {
90 #[allow(clippy::redundant_closure_call)]
91 $flush(self)
92 }
93
94 fn has_external_changes(&self) -> Result<bool, LinkError> {
95 #[allow(clippy::redundant_closure_call)]
96 $external(self)
97 }
98
99 fn reload(&mut self) -> Result<(), LinkError> {
100 #[allow(clippy::redundant_closure_call)]
101 $reload(self)
102 }
103 }
104
105 impl LinksStorageRef<u32> for $type {
106 fn get_link_ref(&self, index: u32) -> Option<&Link> {
107 self.get(index)
108 }
109
110 fn all_link_refs(&self) -> Vec<&Link> {
111 self.all()
112 }
113
114 fn query_link_refs(
115 &self,
116 index: Option<u32>,
117 source: Option<u32>,
118 target: Option<u32>,
119 ) -> Vec<&Link> {
120 self.query(index, source, target)
121 }
122 }
123 };
124}
125
126impl_in_memory_links_storage!(
127 LinkStorage,
128 |storage: &mut LinkStorage, source, target| storage.create(source, target),
129 |storage: &mut LinkStorage| {
130 storage.save().map_err(storage_error)?;
131 storage.refresh_observed_revision()
132 },
133 |storage: &LinkStorage| {
134 Ok(StorageRevision::of(storage.database_path())? != storage.observed_revision())
135 },
136 |storage: &mut LinkStorage| storage.reload_from_disk().map_err(storage_error)
137);
138
139impl_in_memory_links_storage!(
140 PinnedTypesDecorator,
141 |storage: &mut PinnedTypesDecorator, source, target| storage.create(source, target),
142 |storage: &mut PinnedTypesDecorator| {
143 storage.save().map_err(storage_error)?;
144 storage.links_mut().refresh_observed_revision()
145 },
146 |storage: &PinnedTypesDecorator| storage.links().has_external_changes(),
147 |storage: &mut PinnedTypesDecorator| storage.links_mut().reload()
148);
149
150impl_in_memory_links_storage!(
151 NamedTypesDecorator,
152 |storage: &mut NamedTypesDecorator, source, target| storage.create(source, target),
153 |storage: &mut NamedTypesDecorator| {
154 storage.save().map_err(storage_error)?;
155 storage.links_mut().refresh_observed_revision()?;
156 storage.names_links_mut().refresh_observed_revision()
157 },
158 |storage: &NamedTypesDecorator| {
159 Ok(storage.links().has_external_changes()?
160 || storage.names_links().has_external_changes()?)
161 },
162 |storage: &mut NamedTypesDecorator| {
163 storage.links_mut().reload()?;
164 storage.names_links_mut().reload()
165 }
166);
167
168#[allow(dead_code)]
171fn assert_generic_over_address<T: LinkReference, S: LinksStorage<T>>(_storage: &S) {}