symlib_corpus_roundtrip/
symlib_corpus_roundtrip.rs1use std::fs;
2use std::path::{Path, PathBuf};
3
4use kiutils_kicad::SymLibTableFile;
5
6fn usage() -> String {
7 "usage: symlib_corpus_roundtrip <input_dir> <output_dir>".to_string()
8}
9
10fn collect_symlib_files(dir: &Path, files: &mut Vec<PathBuf>) -> Result<(), String> {
11 let entries = fs::read_dir(dir).map_err(|e| format!("read_dir {}: {e}", dir.display()))?;
12 for entry in entries {
13 let entry = entry.map_err(|e| format!("read_dir entry {}: {e}", dir.display()))?;
14 let path = entry.path();
15 if path.is_dir() {
16 collect_symlib_files(&path, files)?;
17 } else if path.file_name().and_then(|s| s.to_str()) == Some("sym-lib-table") {
18 files.push(path);
19 }
20 }
21 Ok(())
22}
23
24fn main() -> Result<(), String> {
25 let mut args = std::env::args().skip(1);
26 let input_dir = args.next().map(PathBuf::from).ok_or_else(usage)?;
27 let output_dir = args.next().map(PathBuf::from).ok_or_else(usage)?;
28
29 let mut files = Vec::new();
30 collect_symlib_files(&input_dir, &mut files)?;
31 files.sort();
32
33 if files.is_empty() {
34 return Err(format!(
35 "no sym-lib-table files found under {}",
36 input_dir.display()
37 ));
38 }
39
40 let mut ok = 0usize;
41 let mut failed = 0usize;
42 for path in files {
43 let rel = path
44 .strip_prefix(&input_dir)
45 .map_err(|e| format!("strip_prefix {}: {e}", path.display()))?;
46 let out_path = output_dir.join(rel);
47 if let Some(parent) = out_path.parent() {
48 fs::create_dir_all(parent)
49 .map_err(|e| format!("create_dir_all {}: {e}", parent.display()))?;
50 }
51
52 let result = (|| -> Result<(), String> {
53 let doc = SymLibTableFile::read(&path).map_err(|e| format!("read: {e}"))?;
54 doc.write(&out_path).map_err(|e| format!("write: {e}"))?;
55 let _ = SymLibTableFile::read(&out_path).map_err(|e| format!("reread: {e}"))?;
56 Ok(())
57 })();
58
59 match result {
60 Ok(()) => {
61 ok += 1;
62 println!("ok: {}", path.display());
63 }
64 Err(err) => {
65 failed += 1;
66 eprintln!("fail: {} -> {}", path.display(), err);
67 }
68 }
69 }
70
71 println!("summary: ok={ok} failed={failed}");
72 if failed > 0 {
73 return Err(format!("{failed} files failed"));
74 }
75 Ok(())
76}