mod builtin;
mod cache;
mod load;
use std::path::Path;
use std::sync::OnceLock;
use crate::diagnostics::DiagnosticReport;
use crate::model::{RegistryCategory, RegistryDocument, RegistryEntry};
use crate::parser::DocumentFormat;
pub use cache::{
cache_dir, cache_path_for_uri, cache_remove, cache_store, is_cached, load_uri_cached,
};
pub use load::{load, load_bytes, validate_document};
#[must_use]
pub fn default_registry() -> &'static RegistryDocument {
static REGISTRY: OnceLock<RegistryDocument> = OnceLock::new();
REGISTRY.get_or_init(builtin::builtin_registry)
}
#[must_use]
pub fn resolve<'a>(registry: &'a RegistryDocument, id: &str) -> Option<&'a RegistryEntry> {
registry.get(id)
}
#[must_use]
pub fn resolve_default(id: &str) -> Option<&'static RegistryEntry> {
resolve(default_registry(), id)
}
pub fn load_merged(path: impl AsRef<Path>) -> Result<RegistryDocument, DiagnosticReport> {
let mut registry = default_registry().clone();
let loaded = load(path)?;
registry.merge(&loaded);
Ok(registry)
}
pub fn load_uri_merged(uri: &str) -> Result<RegistryDocument, DiagnosticReport> {
let mut registry = default_registry().clone();
let loaded = load_uri_cached(uri)?;
registry.merge(&loaded);
Ok(registry)
}
#[must_use]
pub fn is_known_action(action: &str) -> bool {
resolve_default(action).is_some_and(|entry| entry.category == RegistryCategory::SemanticAction)
}
#[must_use]
pub fn is_known_rule(rule: &str) -> bool {
resolve_default(rule).is_some_and(|entry| entry.category == RegistryCategory::Rule)
}
#[must_use]
pub fn is_known_function(function: &str) -> bool {
resolve_default(function).is_some_and(|entry| entry.category == RegistryCategory::Function)
}
pub fn list(registry_path: Option<&Path>) -> Result<Vec<RegistryEntry>, DiagnosticReport> {
let registry = match registry_path {
Some(path) => load_merged(path)?,
None => default_registry().clone(),
};
Ok(registry.list().into_iter().cloned().collect())
}
pub fn resolve_with_path(
id: &str,
registry_path: Option<&Path>,
) -> Result<Option<RegistryEntry>, DiagnosticReport> {
let registry = match registry_path {
Some(path) => load_merged(path)?,
None => default_registry().clone(),
};
Ok(resolve(®istry, id).cloned())
}
pub fn store_uri_cache(
uri: &str,
content: &[u8],
format: DocumentFormat,
) -> Result<std::path::PathBuf, DiagnosticReport> {
cache_store(uri, content, format)
}