use std::{
collections::HashMap,
sync::{Arc, Mutex, OnceLock},
};
use crate::{ansi::Style, errors::RegistryError};
static REGISTRY: OnceLock<Mutex<HashMap<String, Arc<Style>>>> = OnceLock::new();
pub fn insert_style(name: impl Into<String>, style: Style) -> Result<(), RegistryError> {
let name = name.into();
if name.contains('[') || name.contains(']') {
return Err(RegistryError::InvalidName(name));
}
REGISTRY
.get_or_init(|| Mutex::new(HashMap::new()))
.lock()
.unwrap()
.insert(name, Arc::new(style));
Ok(())
}
pub fn set_prefix(name: impl Into<String>, prefix: impl Into<String>) -> Result<(), RegistryError> {
let name = name.into();
let prefix = prefix.into();
let mut map = REGISTRY
.get_or_init(|| Mutex::new(HashMap::new()))
.lock()
.unwrap();
if let Some(style) = map.get_mut(&name) {
let s = Arc::make_mut(style);
s.prefix = Some(prefix);
Ok(())
} else {
Err(RegistryError::UnknownStyle(name))
}
}
pub fn search_registry(query: impl Into<String>) -> Result<Arc<Style>, RegistryError> {
let map = REGISTRY
.get_or_init(|| Mutex::new(HashMap::new()))
.lock()
.unwrap();
let query = query.into();
match map.get(&query) {
Some(style) => Ok(Arc::clone(style)),
None => Err(RegistryError::UnknownStyle(query)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ansi::Style;
fn dummy_style() -> Style {
Style::parse("[bold]").unwrap()
}
#[test]
fn test_insert_style_valid_name_succeeds() {
assert!(insert_style("mytest-style", dummy_style()).is_ok());
}
#[test]
fn test_insert_style_bracket_in_name_rejected() {
assert!(insert_style("[danger]", dummy_style()).is_err());
}
#[test]
fn test_insert_style_open_bracket_rejected() {
let err = insert_style("bad[name", dummy_style()).unwrap_err();
assert!(matches!(err, RegistryError::InvalidName(_)));
}
#[test]
fn test_insert_style_close_bracket_rejected() {
let err = insert_style("bad]name", dummy_style()).unwrap_err();
assert!(matches!(err, RegistryError::InvalidName(_)));
}
#[test]
fn test_insert_style_registered_and_retrievable() {
insert_style("retrieve-test", dummy_style()).unwrap();
assert!(search_registry("retrieve-test").is_ok());
}
#[test]
fn test_search_registry_unknown_returns_error() {
assert!(search_registry("nonexistent-zzzz").is_err());
}
}