use super::document::{Navigable, TextDocument};
use crate::store::declared::Declared;
use crate::store::facts::Facts;
use crate::store::{StorageError, StorageResult};
use amethystate_core::path::{Level, PathRef, StorePath, Stored};
use error_stack::{Report, ResultExt};
pub(super) fn levels<D: TextDocument>(doc: &D, declared: &Declared, path: &StorePath) -> StorePath {
if path.is_root() || declared.covers(path) {
return path.clone();
}
plane_name(doc, path)
}
pub(super) fn node_at<'a, D: TextDocument>(
doc: &'a D,
declared: &Declared,
path: &StorePath,
) -> Option<&'a D::Node> {
if path.is_root() || declared.covers(path) {
return doc.get(path);
}
let root = doc.get(&StorePath::root())?;
if let Some(node) = root.get_child(Stored::whole(path.into())) {
return Some(node);
}
root.get_child(Stored::level(&bare_name(path)?))
}
fn plane_name<D: TextDocument>(doc: &D, path: &StorePath) -> StorePath {
let Some(root) = doc.get(&StorePath::root()) else {
return path.as_one_level();
};
if root.get_child(Stored::whole(path.into())).is_some() {
return path.as_one_level();
}
match bare_name(path) {
Some(bare) if root.get_child(Stored::level(&bare)).is_some() => StorePath::segment(bare),
_ => path.as_one_level(),
}
}
fn bare_name(path: &StorePath) -> Option<Level<'static>> {
let name = path.name().filter(|_| path.len() == 1)?;
let held = PathRef::from(path);
(name != *held.as_str() && StorePath::parse_joined(name.as_str()).is_err())
.then(|| name.into_owned())
}
pub(super) fn at_root(declared: &Declared, key: &StorePath) -> StorageResult<(StorePath, Root)> {
let name = key
.name()
.ok_or_else(|| Report::new(StorageError::Path))
.attach_key(key)
.attach("a document's root handed back a level with no name")?;
let path = match StorePath::parse_joined(name.as_str()) {
Ok(path) if !path.is_root() => path,
_ => key.clone(),
};
let root = match path.len() == 1 && declared.covers(&path) {
true => Root::Tree,
false => Root::Plane,
};
Ok((path, root))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum Root {
Tree,
Plane,
}