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, BodyCardSchema, CardSchema, FieldSchema, FieldType, UiCardSchema,
21    UiFieldSchema,
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) plate: Option<String>,
37    pub(crate) config: QuillConfig,
38    pub(crate) files: FileTreeNode,
39}
40
41impl QuillSource {
42    /// The quill's declared name.
43    pub fn name(&self) -> &str {
44        &self.config.name
45    }
46
47    /// The backend identifier declared in Quill.yaml (e.g. `"typst"`).
48    pub fn backend_id(&self) -> &str {
49        &self.config.backend
50    }
51
52    /// Quill-specific metadata parsed from Quill.yaml.
53    pub fn metadata(&self) -> &HashMap<String, QuillValue> {
54        &self.metadata
55    }
56
57    /// The plate template content, if the quill declares one.
58    pub fn plate(&self) -> Option<&str> {
59        self.plate.as_deref()
60    }
61
62    /// The parsed schema configuration.
63    pub fn config(&self) -> &QuillConfig {
64        &self.config
65    }
66
67    /// The in-memory file tree for this quill.
68    pub fn files(&self) -> &FileTreeNode {
69        &self.files
70    }
71}
72
73impl std::fmt::Debug for QuillSource {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        f.debug_struct("QuillSource")
76            .field("name", &self.config.name)
77            .field("backend_id", &self.config.backend)
78            .field(
79                "plate",
80                &self.plate.as_ref().map(|s| format!("<{} bytes>", s.len())),
81            )
82            .field("files", &"<FileTreeNode>")
83            .finish()
84    }
85}
86
87#[cfg(test)]
88mod tests;