validation_check/
validation_check.rs

1/* examples/validation_check.rs */
2
3use nextjlc::validation::{ValidationReport, validate_gerber_files};
4
5// A helper function to run a validation test case and print the results clearly.
6fn run_test_case(title: &str, files: &[String]) {
7    println!("--- Running Test Case: {} ---", title);
8    println!("Input Files: {:?}", files);
9
10    match validate_gerber_files(files) {
11        Ok(ValidationReport {
12            layer_count,
13            warnings,
14        }) => {
15            println!("\n[VALIDATION PASSED]");
16            println!("   - Detected Copper Layers: {}", layer_count);
17            if warnings.is_empty() {
18                println!("   - Warnings: None");
19            } else {
20                println!("   - Warnings:");
21                for warning in warnings {
22                    println!("     - {}", warning);
23                }
24            }
25        }
26        Err(errors) => {
27            println!("\n[VALIDATION FAILED]");
28            println!("   - Errors:");
29            for error in errors {
30                println!("     - {}", error);
31            }
32        }
33    }
34    println!("\n{}\n", "-".repeat(80));
35}
36
37fn main() {
38    // --- Test Case 1: Complete and Valid 4-Layer Board ---
39    // This is the ideal case, based on your provided file list.
40    // It should pass with no errors and no warnings (assuming all standard files are present).
41    let complete_files: Vec<String> = [
42        "Drill_PTH_Through.DRL",
43        "Gerber_BoardOutlineLayer.GKO",
44        "Gerber_BottomLayer.GBL",
45        "Gerber_BottomPasteMaskLayer.GBP",
46        "Gerber_BottomSilkscreenLayer.GBO",
47        "Gerber_BottomSolderMaskLayer.GBS",
48        "Gerber_InnerLayer1.G1",
49        "Gerber_InnerLayer2.G2",
50        "Gerber_TopLayer.GTL",
51        "Gerber_TopPasteMaskLayer.GTP",
52        "Gerber_TopSilkscreenLayer.GTO",
53        "Gerber_TopSolderMaskLayer.GTS",
54        // "PCB下单必读.txt" is ignored as it doesn't match any standard names.
55    ]
56    .iter()
57    .map(|s| s.to_string())
58    .collect();
59    run_test_case("Complete 4-Layer Board", &complete_files);
60
61    // --- Test Case 2: Missing Board Outline ---
62    // This is a critical error and should cause validation to fail immediately.
63    let mut files_no_outline = complete_files.clone();
64    files_no_outline.retain(|f| !f.starts_with("Gerber_BoardOutlineLayer"));
65    run_test_case("Missing Board Outline (Critical Error)", &files_no_outline);
66
67    // --- Test Case 3: Standard 2-Layer Board (No Inner Layers) ---
68    // This should pass, but might have warnings if we remove paste/silk layers.
69    let mut two_layer_files = complete_files.clone();
70    two_layer_files.retain(|f| !f.starts_with("Gerber_InnerLayer"));
71    run_test_case("Standard 2-Layer Board", &two_layer_files);
72
73    // --- Test Case 4: 2-Layer Board Missing Optional Silkscreen Layers ---
74    // This should pass, but generate two warnings.
75    let mut two_layer_no_silk = two_layer_files.clone();
76    two_layer_no_silk.retain(|f| !f.contains("Silkscreen"));
77    run_test_case(
78        "2-Layer Board without Silkscreen (Warnings)",
79        &two_layer_no_silk,
80    );
81
82    // --- Test Case 5: Invalid Multilayer Board (Missing Bottom Copper) ---
83    // A board with Top and Inner layers MUST have a Bottom layer. This is a critical error.
84    let mut invalid_multilayer = complete_files.clone();
85    invalid_multilayer.retain(|f| !f.starts_with("Gerber_BottomLayer"));
86    run_test_case(
87        "Invalid Multilayer Board - Missing Bottom Copper",
88        &invalid_multilayer,
89    );
90
91    // --- Test Case 6: Minimal Valid 1-Layer Board ---
92    // The absolute minimum required files for a simple single-sided board.
93    // Should pass, but with warnings about missing paste/silk layers.
94    let minimal_one_layer = vec![
95        "Gerber_BoardOutlineLayer.GKO".to_string(),
96        "Gerber_TopLayer.GTL".to_string(),
97        "Gerber_TopSolderMaskLayer.GTS".to_string(),
98        "Drill_PTH_Through.DRL".to_string(), // Drill file is not strictly checked by our rules, but good to have.
99    ];
100    run_test_case("Minimal 1-Layer Board (with Warnings)", &minimal_one_layer);
101
102    // --- Test Case 7: Bottom Layer Present but Missing its Solder Mask ---
103    // This is another critical error.
104    let mut bottom_no_mask = two_layer_files.clone();
105    bottom_no_mask.retain(|f| !f.starts_with("Gerber_BottomSolderMaskLayer"));
106    run_test_case(
107        "2-Layer Board Missing Bottom Solder Mask (Critical Error)",
108        &bottom_no_mask,
109    );
110}