Skip to main content

sbom_tools/diff/
mod.rs

1//! Semantic diff engine for SBOMs.
2//!
3//! This module implements a graph-based semantic diff algorithm inspired by
4//! difftastic, adapted for SBOM comparison.
5//!
6//! # Architecture
7//!
8//! The diff system is built on traits for extensibility:
9//!
10//! - [`ChangeComputer`](traits::ChangeComputer): Trait for computing specific types of changes
11//! - Individual change computers in the [`changes`] module
12//!
13//! # Performance Features
14//!
15//! - **Incremental Diffing**: Cache results and recompute only changed sections
16//! - **Batch Candidate Generation**: Use LSH + cross-ecosystem for large SBOMs
17//!
18//! # Example
19//!
20//! ```ignore
21//! use sbom_tools::diff::{DiffEngine, changes::ComponentChangeComputer};
22//!
23//! let engine = DiffEngine::new();
24//! let result = engine.diff(&old_sbom, &new_sbom);
25//!
26//! // For repeated diffs, use the incremental engine:
27//! use sbom_tools::diff::IncrementalDiffEngine;
28//! let incremental = IncrementalDiffEngine::new(engine);
29//! let result = incremental.diff(&old, &new)?;
30//! if result.was_cached() {
31//!     println!("Cache hit!");
32//! }
33//! ```
34
35pub mod changes;
36mod cost;
37mod engine;
38mod engine_config;
39mod engine_matching;
40mod engine_rules;
41pub mod graph;
42pub mod incremental;
43pub mod multi;
44mod multi_engine;
45mod result;
46pub mod traits;
47
48pub use cost::CostModel;
49pub use engine::{DiffEngine, LargeSbomConfig};
50pub use graph::{GraphDiffConfig, diff_dependency_graph};
51pub use incremental::{
52    CacheHitType, CacheStats, ChangedSections, DiffCache, DiffCacheConfig, DiffCacheKey,
53    IncrementalDiffEngine, IncrementalDiffResult, SectionHashes,
54};
55pub use multi::{
56    ComparisonResult, ComplianceScoreEntry, ComplianceSnapshot, ComponentEvolution,
57    DependencySnapshot, DivergenceType, DivergentComponent, EvolutionSummary,
58    InconsistentComponent, IncrementalChange, LicenseChange as TimelineLicenseChange,
59    LicenseChangeType, MatrixResult, MultiDiffResult, MultiDiffSummary, SbomCluster,
60    SbomClustering, SbomInfo, SecurityImpact, TimelinePair, TimelineResult, VariableComponent,
61    VersionAtPoint, VersionChangeType, VersionSpread, VulnerabilityMatrix, VulnerabilitySnapshot,
62};
63pub use multi_engine::MultiDiffEngine;
64// Only consumer is the TUI Summary tab; gate so `--no-default-features`
65// builds don't carry an unused re-export.
66#[cfg(feature = "tui")]
67pub(crate) use multi_engine::classify_version_strings;
68// TUI multi-dashboard drill-down matches pairwise change entries (whose ids
69// keep the version) against logical variable-component ids.
70#[cfg(feature = "tui")]
71pub(crate) use multi_engine::strip_purl_version;
72pub use result::ml_metric_higher_is_better;
73pub use result::{
74    CategoryDelta, ChangeSet, ChangeType, ComponentChange, ComponentLicenseChange,
75    ConfidenceInterval, DependencyChange, DependencyChangeType, DependencyGraphChange, DiffResult,
76    DiffSummary, FieldChange, GraphChangeImpact, GraphChangeSummary, GraphChangesByImpact,
77    LicenseChange, LicenseChanges, LicenseConflict, MatchInfo, MatchMetrics, MatchScoreComponent,
78    MetadataChange, MetadataChangeKind, MlRegression, QualityDelta, SlaStatus, VexCoverageSummary,
79    VexStatusChange, VulnerabilityChanges, VulnerabilityDetail,
80};
81pub use traits::{
82    ChangeComputer, ComponentChangeSet, ComponentMatches, DependencyChangeSet, LicenseChangeSet,
83    VulnerabilityChangeSet,
84};