quillmark_core/
backend.rs

1//! # Backend Trait
2//!
3//! Backend trait for implementing output format backends.
4//!
5//! ## Overview
6//!
7//! The [`Backend`] trait defines the interface that backends must implement
8//! to support different output formats (PDF, SVG, TXT, etc.).
9//!
10//! ## Trait Definition
11//!
12//! ```rust,ignore
13//! pub trait Backend: Send + Sync {
14//!     fn id(&self) -> &'static str;
15//!     fn supported_formats(&self) -> &'static [OutputFormat];
16//!     fn glue_type(&self) -> &'static str;
17//!     fn register_filters(&self, glue: &mut Glue);
18//!     fn compile(
19//!         &self,
20//!         glue_content: &str,
21//!         quill: &Quill,
22//!         opts: &RenderOptions,
23//!     ) -> Result<Vec<Artifact>, RenderError>;
24//! }
25//! ```
26//!
27//! ## Implementation Guide
28//!
29//! ### Required Methods
30//!
31//! #### `id()`
32//! Return a unique backend identifier (e.g., "typst", "latex").
33//!
34//! #### `supported_formats()`
35//! Return a slice of [`OutputFormat`] variants this backend supports.
36//!
37//! #### `glue_type()`
38//! Return the file extension for glue files (e.g., ".typ", ".tex").
39//!
40//! #### `register_filters()`
41//! Register backend-specific filters with the glue environment.
42//!
43//! ```no_run
44//! # use quillmark_core::{Glue, templating::filter_api::{State, Value, Kwargs, Error}};
45//! # fn string_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
46//! # fn content_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
47//! # fn lines_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
48//! # struct MyBackend;
49//! # impl MyBackend {
50//! fn register_filters(&self, glue: &mut Glue) {
51//!     glue.register_filter("String", string_filter);
52//!     glue.register_filter("Content", content_filter);
53//!     glue.register_filter("Lines", lines_filter);
54//! }
55//! # }
56//! ```
57//!
58//! #### `compile()`
59//! Compile glue content into final artifacts.
60//!
61//! ```no_run
62//! # use quillmark_core::{Quill, RenderOptions, Artifact, OutputFormat, RenderError};
63//! # struct MyBackend;
64//! # impl MyBackend {
65//! fn compile(
66//!     &self,
67//!     glue_content: &str,
68//!     quill: &Quill,
69//!     opts: &RenderOptions,
70//! ) -> Result<Vec<Artifact>, RenderError> {
71//!     // 1. Create compilation environment
72//!     // 2. Load assets from quill
73//!     // 3. Compile glue content
74//!     // 4. Handle errors and map to Diagnostics
75//!     // 5. Return artifacts
76//!     # let compiled_pdf = vec![];
77//!     
78//!     Ok(vec![Artifact {
79//!         bytes: compiled_pdf,
80//!         output_format: OutputFormat::Pdf,
81//!     }])
82//! }
83//! # }
84//! ```
85//!
86//! ## Example Implementation
87//!
88//! See `quillmark-typst` for a complete backend implementation example.
89//!
90//! ## Thread Safety
91//!
92//! The [`Backend`] trait requires `Send + Sync` to enable concurrent rendering.
93//! All backend implementations must be thread-safe.
94
95use crate::error::RenderError;
96use crate::templating::Glue;
97use crate::{Artifact, OutputFormat, Quill, RenderOptions};
98
99/// Backend trait for rendering different output formats
100pub trait Backend: Send + Sync {
101    /// Get the backend identifier (e.g., "typst", "latex")
102    fn id(&self) -> &'static str;
103
104    /// Get supported output formats
105    fn supported_formats(&self) -> &'static [OutputFormat];
106
107    /// Get the glue file extension (e.g., ".typ", ".tex")
108    fn glue_type(&self) -> &'static str;
109
110    /// Register backend-specific filters with the glue environment
111    fn register_filters(&self, glue: &mut Glue);
112
113    /// Compile the glue content into final artifacts
114    fn compile(
115        &self,
116        glue_content: &str,
117        quill: &Quill,
118        opts: &RenderOptions,
119    ) -> Result<Vec<Artifact>, RenderError>;
120}