fsvalidator 0.3.0

A file structure validator
Documentation
#![deny(warnings)]

// You'll need the following feature enabled:
//
// `fsvalidator = { version = "0.2", features = ["toml"] }`
//
use anyhow::Result;

use fsvalidator::from_toml;
use fsvalidator::display::{format_validation_result, COLORS, SYMBOLS};

fn main() -> Result<()> {
    // Print a colorful header
    println!("{}{}Filesystem Validator Example{}", COLORS.bold, COLORS.blue, COLORS.reset);
    println!("{}═════════════════════════{}\n", COLORS.blue, COLORS.reset);

    // Load the validation structure from TOML
    let root = from_toml("examples/basic/fsvalidator.toml")?;
    println!("{}{}Structure Definition:{}\n{root}", COLORS.bold, COLORS.cyan, COLORS.reset);

    let path = "./examples/basic";
    
    // Validate with categorized errors
    let result = root.validate(path);
    
    println!("\n{}{}Validation Results:{}", COLORS.bold, COLORS.magenta, COLORS.reset);
    println!("{}", format_validation_result(&result, path));
    
    // For demonstration, show how to programmatically work with results
    match &result {
        Ok(_) => {
            println!("\n{}{}All checks passed!{}", COLORS.green, SYMBOLS.success, COLORS.reset);
        },
        Err(errors) => {
            // Count errors by category for a summary
            let mut missing_count = 0;
            let mut unexpected_count = 0;
            let mut name_mismatch_count = 0;
            let mut other_count = 0;
            
            // Helper function to count errors by category
            fn count_errors_by_category(error: &fsvalidator::ValidationError, 
                                       missing: &mut usize,
                                       unexpected: &mut usize,
                                       name_mismatch: &mut usize,
                                       other: &mut usize) {
                use fsvalidator::ErrorCategory;
                
                match error.category {
                    ErrorCategory::Missing => *missing += 1,
                    ErrorCategory::Unexpected => *unexpected += 1,
                    ErrorCategory::NameMismatch => *name_mismatch += 1,
                    _ => *other += 1,
                }
                
                for child in &error.children {
                    count_errors_by_category(child, missing, unexpected, name_mismatch, other);
                }
            }
            
            count_errors_by_category(errors, &mut missing_count, &mut unexpected_count, 
                                    &mut name_mismatch_count, &mut other_count);
            
            println!("\n{}{}Error Summary:{}", COLORS.bold, COLORS.red, COLORS.reset);
            println!("  {}{}Missing items:{} {}", COLORS.yellow, SYMBOLS.warning, COLORS.reset, missing_count);
            println!("  {}{}Unexpected items:{} {}", COLORS.cyan, SYMBOLS.warning, COLORS.reset, unexpected_count);
            println!("  {}{}Name mismatches:{} {}", COLORS.magenta, SYMBOLS.warning, COLORS.reset, name_mismatch_count);
            println!("  {}{}Other errors:{} {}", COLORS.red, SYMBOLS.warning, COLORS.reset, other_count);
        }
    }

    Ok(())
}