data_modelling_core/export/
sketch.rs1use crate::export::ExportError;
6use crate::models::sketch::{Sketch, SketchIndex};
7
8pub struct SketchExporter;
10
11impl SketchExporter {
12 pub fn new() -> Self {
14 Self
15 }
16
17 pub fn export(&self, sketch: &Sketch) -> Result<String, ExportError> {
27 let yaml = sketch.to_yaml().map_err(|e| {
28 ExportError::SerializationError(format!("Failed to serialize sketch: {}", e))
29 })?;
30
31 #[cfg(feature = "schema-validation")]
33 {
34 use crate::validation::schema::validate_sketch_internal;
35 validate_sketch_internal(&yaml).map_err(ExportError::ValidationError)?;
36 }
37
38 Ok(yaml)
39 }
40
41 pub fn export_without_validation(&self, sketch: &Sketch) -> Result<String, ExportError> {
46 sketch.to_yaml().map_err(|e| {
47 ExportError::SerializationError(format!("Failed to serialize sketch: {}", e))
48 })
49 }
50
51 pub fn export_index(&self, index: &SketchIndex) -> Result<String, ExportError> {
61 index.to_yaml().map_err(|e| {
62 ExportError::SerializationError(format!("Failed to serialize sketch index: {}", e))
63 })
64 }
65
66 pub fn export_to_directory(
78 &self,
79 sketches: &[Sketch],
80 dir_path: &std::path::Path,
81 workspace_name: &str,
82 ) -> Result<usize, ExportError> {
83 if !dir_path.exists() {
85 std::fs::create_dir_all(dir_path)
86 .map_err(|e| ExportError::IoError(format!("Failed to create directory: {}", e)))?;
87 }
88
89 let mut count = 0;
90 for sketch in sketches {
91 let filename = sketch.filename(workspace_name);
92 let path = dir_path.join(&filename);
93 let yaml = self.export(sketch)?;
94 std::fs::write(&path, yaml).map_err(|e| {
95 ExportError::IoError(format!("Failed to write {}: {}", filename, e))
96 })?;
97 count += 1;
98 }
99
100 Ok(count)
101 }
102
103 pub fn export_domain_to_directory(
116 &self,
117 sketches: &[Sketch],
118 dir_path: &std::path::Path,
119 workspace_name: &str,
120 domain: &str,
121 ) -> Result<usize, ExportError> {
122 let filtered: Vec<&Sketch> = sketches
123 .iter()
124 .filter(|s| s.domain.as_deref() == Some(domain))
125 .collect();
126
127 let domain_dir = dir_path.join(domain);
129 if !domain_dir.exists() {
130 std::fs::create_dir_all(&domain_dir)
131 .map_err(|e| ExportError::IoError(format!("Failed to create directory: {}", e)))?;
132 }
133
134 let mut count = 0;
135 for sketch in filtered {
136 let filename = sketch.filename(workspace_name);
137 let path = domain_dir.join(&filename);
138 let yaml = self.export(sketch)?;
139 std::fs::write(&path, yaml).map_err(|e| {
140 ExportError::IoError(format!("Failed to write {}: {}", filename, e))
141 })?;
142 count += 1;
143 }
144
145 Ok(count)
146 }
147}
148
149impl Default for SketchExporter {
150 fn default() -> Self {
151 Self::new()
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158 use crate::models::sketch::SketchStatus;
159
160 #[test]
161 fn test_export_sketch() {
162 let sketch = Sketch::new(1, "Architecture Diagram", r#"{"elements":[]}"#)
163 .with_status(SketchStatus::Published);
164
165 let exporter = SketchExporter::new();
166 let result = exporter.export_without_validation(&sketch);
167 assert!(result.is_ok());
168 let yaml = result.unwrap();
169 assert!(yaml.contains("title: Architecture Diagram"));
170 assert!(yaml.contains("status: published"));
171 }
172
173 #[test]
174 fn test_export_sketch_index() {
175 let index = SketchIndex::new();
176 let exporter = SketchExporter::new();
177 let result = exporter.export_index(&index);
178 assert!(result.is_ok());
179 let yaml = result.unwrap();
180 assert!(yaml.contains("schemaVersion"));
181 assert!(yaml.contains("nextNumber: 1"));
182 }
183
184 #[test]
185 fn test_export_sketch_with_all_fields() {
186 let sketch = Sketch::new(1, "Sales Domain Architecture", r#"{"elements":[]}"#)
187 .with_status(SketchStatus::Published)
188 .with_domain("sales")
189 .with_description("High-level architecture diagram")
190 .with_thumbnail("thumbnails/sketch-0001.png")
191 .add_author("architect@company.com");
192
193 let exporter = SketchExporter::new();
194 let result = exporter.export_without_validation(&sketch);
195 assert!(result.is_ok());
196 let yaml = result.unwrap();
197 assert!(yaml.contains("domain: sales"));
198 assert!(yaml.contains("thumbnailPath: thumbnails/sketch-0001.png"));
199 }
200}