Development Documentation (main branch) - For stable release docs, see docs.rs/eidetica

eidetica/instance/
backend.rs

1//! Backend wrapper for Instance-level operations
2//!
3//! This module provides the `Backend` struct which wraps `BackendImpl` and provides
4//! a layer for Instance-level operations. Currently it's a thin passthrough,
5//! but will be extended to support both local and remote (RPC) backends in the future.
6
7use std::{any::Any, sync::Arc};
8
9use handle_trait::Handle;
10
11use crate::{
12    Result,
13    backend::{BackendImpl, InstanceMetadata, VerificationStatus},
14    entry::{Entry, ID},
15};
16
17/// Backend wrapper for Instance operations
18///
19/// This struct wraps a `BackendImpl` and provides methods for backend operations.
20/// Currently it's a thin wrapper that delegates all calls to the underlying BackendImpl.
21///
22/// In the future, this will be converted to an enum to support both local and remote
23/// (RPC-based) backends, allowing for transparent local/remote dispatch.
24#[derive(Clone, Handle)]
25pub struct Backend {
26    backend_impl: Arc<dyn BackendImpl>,
27}
28
29impl Backend {
30    /// Create a new Backend wrapping a BackendImpl
31    pub fn new(backend_impl: Arc<dyn BackendImpl>) -> Self {
32        Self { backend_impl }
33    }
34
35    /// Get an entry from the backend
36    pub async fn get(&self, id: &ID) -> Result<Entry> {
37        self.backend_impl.get(id).await
38    }
39
40    /// Get verification status of an entry
41    pub async fn get_verification_status(&self, id: &ID) -> Result<VerificationStatus> {
42        self.backend_impl.get_verification_status(id).await
43    }
44
45    /// Put an entry into the backend with verification status
46    pub async fn put(&self, verification: VerificationStatus, entry: Entry) -> Result<()> {
47        self.backend_impl.put(verification, entry).await
48    }
49
50    /// Put a verified entry (convenience method)
51    pub async fn put_verified(&self, entry: Entry) -> Result<()> {
52        self.backend_impl.put_verified(entry).await
53    }
54
55    /// Put an unverified entry (convenience method)
56    pub async fn put_unverified(&self, entry: Entry) -> Result<()> {
57        self.backend_impl.put_unverified(entry).await
58    }
59
60    /// Update verification status of an entry
61    pub async fn update_verification_status(
62        &self,
63        id: &ID,
64        status: VerificationStatus,
65    ) -> Result<()> {
66        self.backend_impl
67            .update_verification_status(id, status)
68            .await
69    }
70
71    /// Get entries by verification status
72    pub async fn get_entries_by_verification_status(
73        &self,
74        status: VerificationStatus,
75    ) -> Result<Vec<ID>> {
76        self.backend_impl
77            .get_entries_by_verification_status(status)
78            .await
79    }
80
81    /// Get tips for a tree
82    pub async fn get_tips(&self, tree: &ID) -> Result<Vec<ID>> {
83        self.backend_impl.get_tips(tree).await
84    }
85
86    /// Get tips for a specific store within a tree
87    pub async fn get_store_tips(&self, tree: &ID, store: &str) -> Result<Vec<ID>> {
88        self.backend_impl.get_store_tips(tree, store).await
89    }
90
91    /// Get store tips up to specific entries
92    pub async fn get_store_tips_up_to_entries(
93        &self,
94        tree: &ID,
95        store: &str,
96        up_to: &[ID],
97    ) -> Result<Vec<ID>> {
98        self.backend_impl
99            .get_store_tips_up_to_entries(tree, store, up_to)
100            .await
101    }
102
103    /// Get all root entries
104    pub async fn all_roots(&self) -> Result<Vec<ID>> {
105        self.backend_impl.all_roots().await
106    }
107
108    /// Find merge base (common dominator) of entries
109    pub async fn find_merge_base(&self, tree: &ID, store: &str, entry_ids: &[ID]) -> Result<ID> {
110        self.backend_impl
111            .find_merge_base(tree, store, entry_ids)
112            .await
113    }
114
115    /// Collect root to target path
116    pub async fn collect_root_to_target(
117        &self,
118        tree: &ID,
119        store: &str,
120        target: &ID,
121    ) -> Result<Vec<ID>> {
122        self.backend_impl
123            .collect_root_to_target(tree, store, target)
124            .await
125    }
126
127    /// Get all entries in a tree
128    pub async fn get_tree(&self, tree: &ID) -> Result<Vec<Entry>> {
129        self.backend_impl.get_tree(tree).await
130    }
131
132    /// Get all entries in a store
133    pub async fn get_store(&self, tree: &ID, store: &str) -> Result<Vec<Entry>> {
134        self.backend_impl.get_store(tree, store).await
135    }
136
137    /// Get tree entries from tips
138    pub async fn get_tree_from_tips(&self, tree: &ID, tips: &[ID]) -> Result<Vec<Entry>> {
139        self.backend_impl.get_tree_from_tips(tree, tips).await
140    }
141
142    /// Get store entries from tips
143    pub async fn get_store_from_tips(
144        &self,
145        tree: &ID,
146        store: &str,
147        tips: &[ID],
148    ) -> Result<Vec<Entry>> {
149        self.backend_impl
150            .get_store_from_tips(tree, store, tips)
151            .await
152    }
153
154    /// Get cached CRDT state
155    pub async fn get_cached_crdt_state(
156        &self,
157        entry_id: &ID,
158        store: &str,
159    ) -> Result<Option<String>> {
160        self.backend_impl
161            .get_cached_crdt_state(entry_id, store)
162            .await
163    }
164
165    /// Cache CRDT state
166    pub async fn cache_crdt_state(&self, entry_id: &ID, store: &str, state: String) -> Result<()> {
167        self.backend_impl
168            .cache_crdt_state(entry_id, store, state)
169            .await
170    }
171
172    /// Clear CRDT cache
173    pub async fn clear_crdt_cache(&self) -> Result<()> {
174        self.backend_impl.clear_crdt_cache().await
175    }
176
177    /// Get sorted store parents
178    pub async fn get_sorted_store_parents(
179        &self,
180        tree_id: &ID,
181        entry_id: &ID,
182        store: &str,
183    ) -> Result<Vec<ID>> {
184        self.backend_impl
185            .get_sorted_store_parents(tree_id, entry_id, store)
186            .await
187    }
188
189    /// Get path from one entry to others
190    pub async fn get_path_from_to(
191        &self,
192        tree_id: &ID,
193        store: &str,
194        from_id: &ID,
195        to_ids: &[ID],
196    ) -> Result<Vec<ID>> {
197        self.backend_impl
198            .get_path_from_to(tree_id, store, from_id, to_ids)
199            .await
200    }
201
202    /// Get instance metadata
203    pub async fn get_instance_metadata(&self) -> Result<Option<InstanceMetadata>> {
204        self.backend_impl.get_instance_metadata().await
205    }
206
207    /// Set instance metadata
208    pub async fn set_instance_metadata(&self, metadata: &InstanceMetadata) -> Result<()> {
209        self.backend_impl.set_instance_metadata(metadata).await
210    }
211
212    /// Get access to the underlying BackendImpl
213    ///
214    /// This is provided for special operations like downcasting to concrete
215    /// backend types (e.g., for save/load operations on InMemory).
216    /// Use with caution.
217    pub fn as_backend_impl(&self) -> &dyn BackendImpl {
218        &*self.backend_impl
219    }
220
221    /// Get access to the underlying `Arc<dyn BackendImpl>`
222    ///
223    /// This is needed for validation functions and other code that expects
224    /// the Arc wrapper. Returns a reference to the Arc.
225    pub fn as_arc_backend_impl(&self) -> &Arc<dyn BackendImpl> {
226        &self.backend_impl
227    }
228
229    /// Downcast to Any for concrete backend type access
230    ///
231    /// This is primarily used for downcasting to concrete backend types
232    /// (e.g., InMemory) for save/load operations or testing.
233    pub fn as_any(&self) -> &dyn Any {
234        self.backend_impl.as_any()
235    }
236}