use crate::Result;
use crate::types::internal::InternalDocument;
use std::sync::Arc;
pub trait Renderer: Send + Sync {
fn name(&self) -> &str;
fn render(&self, doc: &InternalDocument) -> Result<String>;
}
pub fn register_renderer(renderer: Arc<dyn Renderer>) -> crate::Result<()> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.register(renderer)
}
pub fn unregister_renderer(name: &str) -> crate::Result<()> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.remove(name);
Ok(())
}
pub fn list_renderers() -> Vec<String> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let registry = registry.read();
registry.list()
}
pub fn clear_renderers() -> crate::Result<()> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.reset_to_defaults()
}
#[cfg(test)]
mod tests {
use super::*;
struct TestRenderer {
format_name: &'static str,
}
impl Renderer for TestRenderer {
fn name(&self) -> &str {
self.format_name
}
fn render(&self, doc: &InternalDocument) -> Result<String> {
Ok(format!("rendered {} elements", doc.elements.len()))
}
}
#[test]
fn test_renderer_trait() {
let renderer = TestRenderer {
format_name: "test-format",
};
assert_eq!(renderer.name(), "test-format");
let doc = InternalDocument::new("text/plain");
let result = renderer.render(&doc).unwrap();
assert!(result.contains("rendered"));
}
#[test]
fn test_register_and_list_renderer() {
let renderer = Arc::new(TestRenderer {
format_name: "test-register",
});
register_renderer(renderer).unwrap();
let renderers = list_renderers();
assert!(renderers.contains(&"test-register".to_string()));
unregister_renderer("test-register").unwrap();
}
}