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}