Skip to main content

symlib_corpus_roundtrip/
symlib_corpus_roundtrip.rs

1use 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}