11//! Comprehensive reference-output vs Rust scan parity comparison tool.
22//!
3+ //! Exception: Standalone diagnostic CLI binary with complex parity output
4+ //! formatting. Not library code - splitting would reduce tool readability.
5+ //!
36//! This tool performs deep comparison of UFFS scan outputs to verify that
47//! the Rust implementation produces identical results to the reference output.
58//!
6972use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
7073use std:: collections:: { HashMap , HashSet } ;
7174use std:: env;
72- use std:: path:: Path ;
73-
7475use std:: fs:: File ;
7576use std:: io:: Write ;
77+ use std:: path:: Path ;
7678
7779use anyhow:: { Context , Result } ;
7880use rayon:: prelude:: * ;
7981use uffs_diag:: parity:: { ComparisonResults , FieldStats } ;
80- use uffs_polars:: { CsvReadOptions , DataFrame , SerReader , StringChunked } ;
8182// Wire in crate dependencies for version-locking
8283use uffs_mft as _;
84+ use uffs_polars:: { CsvReadOptions , DataFrame , SerReader , StringChunked } ;
8385
8486// ============================================================================
8587// Column Name Mappings (reference output <-> Rust)
@@ -635,23 +637,44 @@ fn print_results(results: &ComparisonResults) {
635637 println ! ( " Rust: {}" , results. rust_file) ;
636638
637639 println ! ( "\n 📊 ROW COUNTS" ) ;
638- println ! ( " Reference rows: {:>8}" , format_num( results. reference_total_rows) ) ;
640+ println ! (
641+ " Reference rows: {:>8}" ,
642+ format_num( results. reference_total_rows)
643+ ) ;
639644 println ! ( " Rust rows: {:>12}" , format_num( results. rust_total_rows) ) ;
640645 let diff = results. rust_total_rows as i64 - results. reference_total_rows as i64 ;
641646 println ! ( " Difference: {:>+12}" , diff) ;
642647
643648 println ! ( "\n 🔗 PATH MATCHING" ) ;
644- println ! ( " Common paths: {:>12}" , format_num( results. common_paths) ) ;
645- println ! ( " Reference only: {:>12}" , format_num( results. reference_only_paths) ) ;
646- println ! ( " Rust only: {:>12}" , format_num( results. rust_only_paths) ) ;
649+ println ! (
650+ " Common paths: {:>12}" ,
651+ format_num( results. common_paths)
652+ ) ;
653+ println ! (
654+ " Reference only: {:>12}" ,
655+ format_num( results. reference_only_paths)
656+ ) ;
657+ println ! (
658+ " Rust only: {:>12}" ,
659+ format_num( results. rust_only_paths)
660+ ) ;
647661 println ! ( " Match rate: {:>11.4}%" , results. path_match_rate) ;
648662
649663 println ! ( "\n 📎 ALTERNATE DATA STREAMS (ADS)" ) ;
650- println ! ( " Reference ADS: {:>10}" , format_num( results. reference_ads_count) ) ;
651- println ! ( " Rust ADS entries: {:>10}" , format_num( results. rust_ads_count) ) ;
664+ println ! (
665+ " Reference ADS: {:>10}" ,
666+ format_num( results. reference_ads_count)
667+ ) ;
668+ println ! (
669+ " Rust ADS entries: {:>10}" ,
670+ format_num( results. rust_ads_count)
671+ ) ;
652672
653673 println ! ( "\n 📈 FIELD-BY-FIELD COMPARISON" ) ;
654- println ! ( "{:>20} {:>12} {:>12} {:>10} {:>12}" , "Field" , "Compared" , "Matches" , "Rate" , "Max Diff" ) ;
674+ println ! (
675+ "{:>20} {:>12} {:>12} {:>10} {:>12}" ,
676+ "Field" , "Compared" , "Matches" , "Rate" , "Max Diff"
677+ ) ;
655678 println ! ( "{}" , "-" . repeat( 70 ) ) ;
656679
657680 let mut fields: Vec < _ > = results. field_stats . keys ( ) . collect ( ) ;
@@ -666,7 +689,11 @@ fn print_results(results: &ComparisonResults) {
666689 format_num( stats. total_compared as usize ) ,
667690 format_num( stats. exact_matches as usize ) ,
668691 stats. match_rate( ) ,
669- if stats. max_abs_diff > 0.0 { format!( "{:.0}" , stats. max_abs_diff) } else { "-" . to_string( ) }
692+ if stats. max_abs_diff > 0.0 {
693+ format!( "{:.0}" , stats. max_abs_diff)
694+ } else {
695+ "-" . to_string( )
696+ }
670697 ) ;
671698 }
672699 }
@@ -714,7 +741,10 @@ fn print_results(results: &ComparisonResults) {
714741 } else {
715742 println ! ( "\n ⚠️ DIFFERENCES DETECTED:" ) ;
716743 if results. reference_only_paths > 0 {
717- println ! ( " - {} paths missing from Rust" , results. reference_only_paths) ;
744+ println ! (
745+ " - {} paths missing from Rust" ,
746+ results. reference_only_paths
747+ ) ;
718748 }
719749 if results. rust_only_paths > 0 {
720750 println ! ( " - {} extra paths in Rust" , results. rust_only_paths) ;
@@ -733,7 +763,11 @@ fn write_markdown_report(results: &ComparisonResults, path: &Path) -> Result<()>
733763
734764 writeln ! ( f, "# UFFS Scan Parity Report" ) ?;
735765 writeln ! ( f) ?;
736- writeln ! ( f, "Generated: {}" , chrono:: Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ) ?;
766+ writeln ! (
767+ f,
768+ "Generated: {}" ,
769+ chrono:: Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" )
770+ ) ?;
737771 writeln ! ( f) ?;
738772
739773 writeln ! ( f, "## Files Compared" ) ?;
@@ -748,7 +782,11 @@ fn write_markdown_report(results: &ComparisonResults, path: &Path) -> Result<()>
748782 writeln ! ( f) ?;
749783 writeln ! ( f, "| Metric | Count |" ) ?;
750784 writeln ! ( f, "|--------|------:|" ) ?;
751- writeln ! ( f, "| Reference rows | {} |" , format_num( results. reference_total_rows) ) ?;
785+ writeln ! (
786+ f,
787+ "| Reference rows | {} |" ,
788+ format_num( results. reference_total_rows)
789+ ) ?;
752790 writeln ! ( f, "| Rust rows | {} |" , format_num( results. rust_total_rows) ) ?;
753791 let diff = results. rust_total_rows as i64 - results. reference_total_rows as i64 ;
754792 writeln ! ( f, "| Difference | {:+} |" , diff) ?;
@@ -759,16 +797,28 @@ fn write_markdown_report(results: &ComparisonResults, path: &Path) -> Result<()>
759797 writeln ! ( f, "| Metric | Count |" ) ?;
760798 writeln ! ( f, "|--------|------:|" ) ?;
761799 writeln ! ( f, "| Common paths | {} |" , format_num( results. common_paths) ) ?;
762- writeln ! ( f, "| Reference only | {} |" , format_num( results. reference_only_paths) ) ?;
800+ writeln ! (
801+ f,
802+ "| Reference only | {} |" ,
803+ format_num( results. reference_only_paths)
804+ ) ?;
763805 writeln ! ( f, "| Rust only | {} |" , format_num( results. rust_only_paths) ) ?;
764- writeln ! ( f, "| **Match rate** | **{:.4}%** |" , results. path_match_rate) ?;
806+ writeln ! (
807+ f,
808+ "| **Match rate** | **{:.4}%** |" ,
809+ results. path_match_rate
810+ ) ?;
765811 writeln ! ( f) ?;
766812
767813 writeln ! ( f, "## Alternate Data Streams (ADS)" ) ?;
768814 writeln ! ( f) ?;
769815 writeln ! ( f, "| Source | ADS Count |" ) ?;
770816 writeln ! ( f, "|--------|----------:|" ) ?;
771- writeln ! ( f, "| Reference | {} |" , format_num( results. reference_ads_count) ) ?;
817+ writeln ! (
818+ f,
819+ "| Reference | {} |" ,
820+ format_num( results. reference_ads_count)
821+ ) ?;
772822 writeln ! ( f, "| Rust | {} |" , format_num( results. rust_ads_count) ) ?;
773823 writeln ! ( f) ?;
774824
@@ -790,7 +840,11 @@ fn write_markdown_report(results: &ComparisonResults, path: &Path) -> Result<()>
790840 format_num( stats. total_compared as usize ) ,
791841 format_num( stats. exact_matches as usize ) ,
792842 stats. match_rate( ) ,
793- if stats. max_abs_diff > 0.0 { format!( "{:.0}" , stats. max_abs_diff) } else { "-" . to_string( ) }
843+ if stats. max_abs_diff > 0.0 {
844+ format!( "{:.0}" , stats. max_abs_diff)
845+ } else {
846+ "-" . to_string( )
847+ }
794848 ) ?;
795849 }
796850 }
@@ -803,12 +857,19 @@ fn write_markdown_report(results: &ComparisonResults, path: &Path) -> Result<()>
803857 writeln ! ( f, "## Summary" ) ?;
804858 writeln ! ( f) ?;
805859 if all_match {
806- writeln ! ( f, "✅ **PERFECT PARITY** - All paths and fields match exactly!" ) ?;
860+ writeln ! (
861+ f,
862+ "✅ **PERFECT PARITY** - All paths and fields match exactly!"
863+ ) ?;
807864 } else {
808865 writeln ! ( f, "⚠️ **DIFFERENCES DETECTED**" ) ?;
809866 writeln ! ( f) ?;
810867 if results. reference_only_paths > 0 {
811- writeln ! ( f, "- {} paths missing from Rust" , results. reference_only_paths) ?;
868+ writeln ! (
869+ f,
870+ "- {} paths missing from Rust" ,
871+ results. reference_only_paths
872+ ) ?;
812873 }
813874 if results. rust_only_paths > 0 {
814875 writeln ! ( f, "- {} extra paths in Rust" , results. rust_only_paths) ?;
0 commit comments