icydb_core/db/registry/
registry.rs1use crate::{
2 db::{
3 data::DataStore,
4 index::IndexStore,
5 registry::{StoreHandle, StoreRegistryError},
6 },
7 error::InternalError,
8};
9use std::{cell::RefCell, thread::LocalKey};
10
11#[derive(Default)]
21pub struct StoreRegistry {
22 stores: Vec<(&'static str, StoreHandle)>,
23}
24
25impl StoreRegistry {
26 #[must_use]
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn iter(&self) -> impl Iterator<Item = (&'static str, StoreHandle)> {
38 self.stores.iter().copied()
39 }
40
41 pub fn register_store(
43 &mut self,
44 name: &'static str,
45 data: &'static LocalKey<RefCell<DataStore>>,
46 index: &'static LocalKey<RefCell<IndexStore>>,
47 ) -> Result<(), InternalError> {
48 if self
49 .stores
50 .iter()
51 .any(|(existing_name, _)| *existing_name == name)
52 {
53 return Err(StoreRegistryError::StoreAlreadyRegistered(name.to_string()).into());
54 }
55
56 if let Some(existing_name) =
58 self.stores
59 .iter()
60 .find_map(|(existing_name, existing_handle)| {
61 (std::ptr::eq(existing_handle.data_store(), data)
62 && std::ptr::eq(existing_handle.index_store(), index))
63 .then_some(*existing_name)
64 })
65 {
66 return Err(StoreRegistryError::StoreHandlePairAlreadyRegistered {
67 name: name.to_string(),
68 existing_name: existing_name.to_string(),
69 }
70 .into());
71 }
72
73 self.stores.push((name, StoreHandle::new(data, index)));
74
75 Ok(())
76 }
77
78 pub fn try_get_store(&self, path: &str) -> Result<StoreHandle, InternalError> {
80 self.stores
81 .iter()
82 .find_map(|(existing_path, handle)| (*existing_path == path).then_some(*handle))
83 .ok_or_else(|| StoreRegistryError::StoreNotFound(path.to_string()).into())
84 }
85}