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_extension_types(&self) -> &'static [&'static str];
17//! fn allow_auto_glue(&self) -> bool;
18//! fn register_filters(&self, glue: &mut Glue);
19//! fn compile(
20//! &self,
21//! glue_content: &str,
22//! quill: &Quill,
23//! opts: &RenderOptions,
24//! ) -> Result<RenderResult, RenderError>;
25//! }
26//! ```
27//!
28//! ## Implementation Guide
29//!
30//! ### Required Methods
31//!
32//! #### `id()`
33//! Return a unique backend identifier (e.g., "typst", "latex").
34//!
35//! #### `supported_formats()`
36//! Return a slice of [`OutputFormat`] variants this backend supports.
37//!
38//! #### `glue_extension_types()`
39//! Return the file extensions for glue files (e.g., &[".typ"], &[".tex"]).
40//! Return an empty array to disable custom glue files.
41//!
42//! #### `allow_auto_glue()`
43//! Return whether automatic JSON glue generation is allowed.
44//!
45//! #### `register_filters()`
46//! Register backend-specific filters with the glue environment.
47//!
48//! ```no_run
49//! # use quillmark_core::{Glue, templating::filter_api::{State, Value, Kwargs, Error}};
50//! # fn string_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
51//! # fn content_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
52//! # fn lines_filter(_: &State, v: Value, _: Kwargs) -> Result<Value, Error> { Ok(v) }
53//! # struct MyBackend;
54//! # impl MyBackend {
55//! fn register_filters(&self, glue: &mut Glue) {
56//! glue.register_filter("String", string_filter);
57//! glue.register_filter("Content", content_filter);
58//! glue.register_filter("Lines", lines_filter);
59//! }
60//! # }
61//! ```
62//!
63//! #### `compile()`
64//! Compile glue content into final artifacts.
65//!
66//! ```no_run
67//! # use quillmark_core::{Quill, RenderOptions, Artifact, OutputFormat, RenderError, RenderResult};
68//! # struct MyBackend;
69//! # impl MyBackend {
70//! fn compile(
71//! &self,
72//! glue_content: &str,
73//! quill: &Quill,
74//! opts: &RenderOptions,
75//! ) -> Result<RenderResult, RenderError> {
76//! // 1. Create compilation environment
77//! // 2. Load assets from quill
78//! // 3. Compile glue content
79//! // 4. Handle errors and map to Diagnostics
80//! // 5. Return RenderResult with artifacts and output format
81//! # let compiled_pdf = vec![];
82//! # let format = OutputFormat::Pdf;
83//!
84//! let artifacts = vec![Artifact {
85//! bytes: compiled_pdf,
86//! output_format: format,
87//! }];
88//!
89//! Ok(RenderResult::new(artifacts, format))
90//! }
91//! # }
92//! ```
93//!
94//! ## Example Implementation
95//!
96//! See `quillmark-typst` for a complete backend implementation example.
97//!
98//! ## Thread Safety
99//!
100//! The [`Backend`] trait requires `Send + Sync` to enable concurrent rendering.
101//! All backend implementations must be thread-safe.
102
103use crate::error::RenderError;
104use crate::templating::Glue;
105use crate::{OutputFormat, Quill, RenderOptions};
106
107/// Backend trait for rendering different output formats
108pub trait Backend: Send + Sync {
109 /// Get the backend identifier (e.g., "typst", "latex")
110 fn id(&self) -> &'static str;
111
112 /// Get supported output formats
113 fn supported_formats(&self) -> &'static [OutputFormat];
114
115 /// Get the glue file extensions accepted by this backend (e.g., &[".typ", ".tex"])
116 /// Returns an empty array to disable custom glue files.
117 fn glue_extension_types(&self) -> &'static [&'static str];
118
119 /// Whether this backend allows automatic JSON glue generation
120 fn allow_auto_glue(&self) -> bool;
121
122 /// Register backend-specific filters with the glue environment
123 fn register_filters(&self, glue: &mut Glue);
124
125 /// Compile the glue content into final artifacts
126 fn compile(
127 &self,
128 glue_content: &str,
129 quill: &Quill,
130 opts: &RenderOptions,
131 ) -> Result<crate::RenderResult, RenderError>;
132}