use std::sync::Arc;
use crate::Result;
use crate::plugins::Plugin;
use crate::types::ExtractedDocument;
use crate::types::internal::InternalDocument;
pub trait Renderer: Plugin {
fn render_result(&self, result: &ExtractedDocument) -> Result<String> {
Ok(result.content.clone())
}
}
pub(crate) trait InternalRenderer: Plugin {
fn render(&self, doc: &InternalDocument) -> Result<String>;
}
impl<T> Renderer for T
where
T: InternalRenderer + ?Sized,
{
fn render_result(&self, result: &ExtractedDocument) -> Result<String> {
let doc = InternalDocument::from(result.clone());
InternalRenderer::render(self, &doc)
}
}
pub fn register_renderer(renderer: Arc<dyn Renderer>) -> 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) -> Result<()> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.remove(name)
}
pub fn list_renderers() -> Result<Vec<String>> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let registry = registry.read();
Ok(registry.list())
}
pub fn clear_renderers() -> Result<()> {
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.clear_all()
}
#[cfg(test)]
mod tests {
use super::*;
struct MockRenderer {
format: &'static str,
}
impl Plugin for MockRenderer {
fn name(&self) -> &str {
self.format
}
}
impl InternalRenderer for MockRenderer {
fn render(&self, doc: &crate::types::internal::InternalDocument) -> crate::Result<String> {
Ok(format!("mock-{}-{}", self.format, doc.elements.len()))
}
}
#[test]
fn register_list_unregister_roundtrip() {
register_renderer(Arc::new(MockRenderer { format: "test-fmt-a" })).unwrap();
assert!(list_renderers().unwrap().contains(&"test-fmt-a".to_string()));
unregister_renderer("test-fmt-a").unwrap();
assert!(!list_renderers().unwrap().contains(&"test-fmt-a".to_string()));
}
#[test]
fn register_list_clear_list_roundtrip() {
register_renderer(Arc::new(MockRenderer { format: "test-fmt-b" })).unwrap();
assert!(list_renderers().unwrap().contains(&"test-fmt-b".to_string()));
clear_renderers().unwrap();
assert!(list_renderers().unwrap().is_empty());
use crate::plugins::registry::get_renderer_registry;
let registry = get_renderer_registry();
let mut registry = registry.write();
registry.reset_to_defaults().unwrap();
}
}