quillmark_core/quill/
load.rs1use crate::error::{Diagnostic, Severity};
3use crate::value::QuillValue;
4
5use super::{FileTreeNode, QuillConfig, QuillSource};
6
7fn diag(message: impl Into<String>, code: &str) -> Diagnostic {
8 Diagnostic::new(Severity::Error, message.into()).with_code(code.to_string())
9}
10
11impl QuillSource {
12 pub fn from_tree(root: FileTreeNode) -> Result<Self, Vec<Diagnostic>> {
29 let quill_yaml_bytes = root.get_file("Quill.yaml").ok_or_else(|| {
30 vec![diag(
31 "Quill.yaml not found in file tree",
32 "quill::missing_file",
33 )]
34 })?;
35
36 let quill_yaml_content = String::from_utf8(quill_yaml_bytes.to_vec()).map_err(|e| {
37 vec![diag(
38 format!("Quill.yaml is not valid UTF-8: {}", e),
39 "quill::invalid_utf8",
40 )]
41 })?;
42
43 let (config, _warnings) = QuillConfig::from_yaml_with_warnings(&quill_yaml_content)?;
46
47 Self::from_config(config, root)
48 }
49
50 fn from_config(config: QuillConfig, root: FileTreeNode) -> Result<Self, Vec<Diagnostic>> {
52 let mut metadata: std::collections::HashMap<String, QuillValue> =
53 std::collections::HashMap::new();
54
55 metadata.insert(
56 "backend".to_string(),
57 QuillValue::from_json(serde_json::Value::String(config.backend.clone())),
58 );
59
60 metadata.insert(
61 "description".to_string(),
62 QuillValue::from_json(serde_json::Value::String(config.description.clone())),
63 );
64
65 metadata.insert(
66 "author".to_string(),
67 QuillValue::from_json(serde_json::Value::String(config.author.clone())),
68 );
69
70 metadata.insert(
71 "version".to_string(),
72 QuillValue::from_json(serde_json::Value::String(config.version.clone())),
73 );
74
75 for (key, value) in &config.backend_config {
77 metadata.insert(format!("{}_{}", config.backend, key), value.clone());
78 }
79
80 let plate_content: Option<String> = if let Some(ref plate_file_name) = config.plate_file {
82 let plate_bytes = root.get_file(plate_file_name).ok_or_else(|| {
83 vec![diag(
84 format!("Plate file '{}' not found in file tree", plate_file_name),
85 "quill::plate_missing",
86 )]
87 })?;
88
89 let content = String::from_utf8(plate_bytes.to_vec()).map_err(|e| {
90 vec![diag(
91 format!("Plate file '{}' is not valid UTF-8: {}", plate_file_name, e),
92 "quill::invalid_utf8",
93 )]
94 })?;
95 Some(content)
96 } else {
97 None
98 };
99
100 let source = QuillSource {
101 metadata,
102 plate: plate_content,
103 config,
104 files: root,
105 };
106
107 Ok(source)
108 }
109}