Skip to main content

sheets_diff/
lib.rs

1// Suppress dead_code for intentional public-API-only variants.
2#![allow(dead_code)]
3//! # sheets-diff
4//!
5//! Structured diff engine for Microsoft Excel `.xlsx` workbooks.
6//!
7//! ## Quick start
8//!
9//! ```rust,no_run
10//! use sheets_diff::compare_paths;
11//!
12//! let diff = compare_paths("old.xlsx", "new.xlsx")?;
13//! println!("changed cells: {}", diff.summary.cells_changed);
14//! # Ok::<(), sheets_diff::SheetsDiffError>(())
15//! ```
16//!
17//! ## Input sources
18//!
19//! | Function | When to use |
20//! |---|---|
21//! | [`compare_paths`] | Simplest; caller provides file paths |
22//! | [`compare_bytes`] | You already have the bytes (e.g. from a cache or repo) |
23//! | [`compare_readers`] | You have open `Read + Seek` handles |
24//! | `compare_*_with_options` variants | Any of the above plus [`DiffOptions`] |
25//!
26//! See [`DiffOptions`] / [`DiffOptionsBuilder`] for all configuration knobs.
27
28// ---------------------------------------------------------------------------
29// Internal modules (not pub)
30// ---------------------------------------------------------------------------
31
32pub mod address;
33mod align;
34mod diff;
35mod error;
36mod matcher;
37mod meta;
38mod objects;
39mod normalize;
40mod open;
41
42pub mod compare;
43
44// ---------------------------------------------------------------------------
45// Public modules
46// ---------------------------------------------------------------------------
47
48/// Typed result model (`WorkbookDiff`, `SheetDiff`, `CellDiff`, `CellValue`, …).
49pub mod model;
50
51/// Comparison options and builder (`DiffOptions`, `DiffOptionsBuilder`, …).
52pub mod options;
53
54/// Output formatters (text summary, unified diff).
55pub mod output;
56
57// ---------------------------------------------------------------------------
58// Re-exports — the stable public API surface (RFC-002, RFC-031)
59// ---------------------------------------------------------------------------
60
61// Error types
62pub use error::{LimitKind, OpenErrorKind, ReadErrorKind, SheetsDiffError};
63
64// Model
65pub use model::{
66    AlignmentSummary,
67    DiffMetrics,
68    CellChangeKind,
69    CellDateTime,
70    CellDiff,
71    CellDisplay,
72    CellDuration,
73    CellError,
74    CellNumberFormat,
75    CellSnapshot,
76    CellValue,
77    DateTimeKind,
78    DiagnosticKind,
79    DiagnosticLocation,
80    DiagnosticSummary,
81    Diagnostic,
82    DiffStage,
83    DiffSummary,
84    DisplaySource,
85    FormatChange,
86    FormulaChange,
87    FormulaText,
88    MatchConfidence,
89    Severity,
90    SheetChange,
91    SheetDiff,
92    SheetMatchReason,
93    SheetRef,
94    SheetSummary,
95    Side,
96    SourceDescription,
97    SourceKind,
98    ValueChange,
99    ValueDifferenceKind,
100    WorkbookChange,
101    WorkbookDiff,
102    WorkbookObjectChange,
103    WorkbookSideInfo,
104};
105
106// Address
107pub use address::{CellAddress, ComparedRange, MAX_COL, MAX_COL_LABEL, MAX_ROW};
108
109// Options
110pub use objects::ObjectCompareMode;
111pub use options::{
112    AlignmentMode,
113    Cancellation,
114    ComparisonOptions,
115    DateComparePolicy,
116    DiagnosticOptions,
117    DiffEvent,
118    DiffOptions,
119    DiffOptionsBuilder,
120    ExecutionMode,
121    ExecutionOptions,
122    FormatCompareMode,
123    FormulaCompareMode,
124    Limits,
125    MatchingOptions,
126    NumberComparePolicy,
127    NumericTypePolicy,
128    OutputOptions,
129    ProgressSink,
130    SheetMatchingMode,
131    TypeMismatchPolicy,
132    ValueCompareOptions,
133};
134
135// ---------------------------------------------------------------------------
136// Public entry points (RFC-033 §12)
137// ---------------------------------------------------------------------------
138
139use std::io::{Read, Seek};
140use std::path::Path;
141
142/// Compare two workbooks given their filesystem paths.
143///
144/// Uses [`DiffOptions::default()`].
145pub fn compare_paths(
146    old: impl AsRef<Path>,
147    new: impl AsRef<Path>,
148) -> Result<WorkbookDiff, SheetsDiffError> {
149    diff::run_compare_paths(old, new, DiffOptions::default())
150}
151
152/// Compare two workbooks given their filesystem paths, with explicit options.
153pub fn compare_paths_with_options(
154    old: impl AsRef<Path>,
155    new: impl AsRef<Path>,
156    opts: DiffOptions,
157) -> Result<WorkbookDiff, SheetsDiffError> {
158    diff::run_compare_paths(old, new, opts)
159}
160
161/// Compare two workbooks given byte slices.
162pub fn compare_bytes(
163    old: impl AsRef<[u8]>,
164    new: impl AsRef<[u8]>,
165) -> Result<WorkbookDiff, SheetsDiffError> {
166    diff::run_compare_bytes(old, new, DiffOptions::default())
167}
168
169/// Compare two workbooks given byte slices, with explicit options.
170pub fn compare_bytes_with_options(
171    old: impl AsRef<[u8]>,
172    new: impl AsRef<[u8]>,
173    opts: DiffOptions,
174) -> Result<WorkbookDiff, SheetsDiffError> {
175    diff::run_compare_bytes(old, new, opts)
176}
177
178/// Compare two workbooks given `Read + Seek` readers.
179///
180/// `.xlsx` is ZIP-based and requires seeking.
181pub fn compare_readers<R1, R2>(
182    old: R1,
183    new: R2,
184) -> Result<WorkbookDiff, SheetsDiffError>
185where
186    R1: Read + Seek,
187    R2: Read + Seek,
188{
189    diff::run_compare_readers(old, new, DiffOptions::default())
190}
191
192/// Compare two workbooks given `Read + Seek` readers, with explicit options.
193pub fn compare_readers_with_options<R1, R2>(
194    old: R1,
195    new: R2,
196    opts: DiffOptions,
197) -> Result<WorkbookDiff, SheetsDiffError>
198where
199    R1: Read + Seek,
200    R2: Read + Seek,
201{
202    diff::run_compare_readers(old, new, opts)
203}