use std::collections::BTreeMap;
use std::sync::Arc;
use hashtree_core::{Cid, HashTree, HashTreeConfig, Store};
use crate::helpers::find_manifest_cid;
use crate::{CollectionDefinition, CollectionError, MANIFEST_BY_ID};
#[derive(Debug, Clone, Default, PartialEq)]
pub struct CollectionState {
pub by_id_root: Option<Cid>,
pub key_roots: BTreeMap<String, Option<Cid>>,
pub search_roots: BTreeMap<String, Option<Cid>>,
}
impl CollectionState {
pub fn key_root(&self, name: &str) -> Option<&Cid> {
self.key_roots.get(name).and_then(Option::as_ref)
}
pub fn search_root(&self, name: &str) -> Option<&Cid> {
self.search_roots.get(name).and_then(Option::as_ref)
}
}
#[derive(Debug, Clone, Default)]
pub struct CollectionOptions {
pub btree_order: Option<usize>,
}
pub fn create_empty_collection_state<T>(definition: &CollectionDefinition<T>) -> CollectionState {
CollectionState {
by_id_root: None,
key_roots: definition
.key_indexes()
.iter()
.map(|index| (index.name().to_string(), None))
.collect(),
search_roots: definition
.search_indexes()
.iter()
.map(|index| (index.name().to_string(), None))
.collect(),
}
}
pub async fn load_collection_state<S: Store, T>(
store: Arc<S>,
definition: &CollectionDefinition<T>,
root: Option<&Cid>,
) -> Result<CollectionState, CollectionError> {
let mut state = create_empty_collection_state(definition);
let Some(root) = root else {
return Ok(state);
};
let tree = HashTree::new(HashTreeConfig::new(store));
let entries = tree.list_directory(root).await?;
state.by_id_root = find_manifest_cid(&entries, MANIFEST_BY_ID);
for index in definition.key_indexes() {
state.key_roots.insert(
index.name().to_string(),
find_manifest_cid(&entries, index.name()),
);
}
for index in definition.search_indexes() {
state.search_roots.insert(
index.name().to_string(),
find_manifest_cid(&entries, index.name()),
);
}
Ok(state)
}