Skip to main content

quillmark_core/
quill.rs

1//! Quill source bundle types and implementations.
2
3mod blueprint;
4mod config;
5mod formats;
6mod ignore;
7mod load;
8mod query;
9mod schema;
10mod schema_yaml;
11mod tree;
12mod types;
13pub(crate) mod validation;
14
15pub use config::{CoercionError, QuillConfig};
16pub use ignore::QuillIgnore;
17pub use schema::build_transform_schema;
18pub use tree::FileTreeNode;
19pub use types::{
20    field_key, ui_key, BodyLeafSchema, FieldSchema, FieldType, LeafSchema, UiFieldSchema,
21    UiLeafSchema,
22};
23
24use std::collections::HashMap;
25
26use crate::value::QuillValue;
27
28/// A quill source bundle — pure data parsed from an authored quill directory.
29///
30/// A `QuillSource` is the file-bundle, config, and metadata; it has no rendering
31/// ability. The engine composes a `QuillSource` with a resolved backend into a
32/// renderable `Quill` (see `quillmark::Quill`).
33#[derive(Clone)]
34pub struct QuillSource {
35    pub(crate) metadata: HashMap<String, QuillValue>,
36    pub(crate) name: String,
37    pub(crate) backend_id: String,
38    pub(crate) plate: Option<String>,
39    pub(crate) example: Option<String>,
40    pub(crate) config: QuillConfig,
41    pub(crate) files: FileTreeNode,
42}
43
44impl QuillSource {
45    /// The quill's declared name.
46    pub fn name(&self) -> &str {
47        &self.name
48    }
49
50    /// The backend identifier declared in Quill.yaml (e.g. `"typst"`).
51    pub fn backend_id(&self) -> &str {
52        &self.backend_id
53    }
54
55    /// Quill-specific metadata parsed from Quill.yaml.
56    pub fn metadata(&self) -> &HashMap<String, QuillValue> {
57        &self.metadata
58    }
59
60    /// The plate template content, if the quill declares one.
61    pub fn plate(&self) -> Option<&str> {
62        self.plate.as_deref()
63    }
64
65    /// The example Markdown content, if the quill ships one.
66    pub fn example(&self) -> Option<&str> {
67        self.example.as_deref()
68    }
69
70    /// The parsed schema configuration.
71    pub fn config(&self) -> &QuillConfig {
72        &self.config
73    }
74
75    /// The in-memory file tree for this quill.
76    pub fn files(&self) -> &FileTreeNode {
77        &self.files
78    }
79}
80
81impl std::fmt::Debug for QuillSource {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        f.debug_struct("QuillSource")
84            .field("name", &self.name)
85            .field("backend_id", &self.backend_id)
86            .field(
87                "plate",
88                &self.plate.as_ref().map(|s| format!("<{} bytes>", s.len())),
89            )
90            .field("example", &self.example.is_some())
91            .field("files", &"<FileTreeNode>")
92            .finish()
93    }
94}
95
96#[cfg(test)]
97mod tests;