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}