2 releases
0.1.1 | Jun 22, 2019 |
---|---|
0.1.0 | Feb 17, 2019 |
#1498 in Data structures
89KB
2K
SLoC
visit_diff
: analyzing structural differences in Rust
This is a library for easily comparing Rust data structures to detect differences. This is useful, for example, when reporting a test failure.
The simplest use case:
-
Put a
#[derive(Diff)]
annotation on your type. -
Replace
assert_eq!
withassert_eq_diff!
.
Now your error messages will highlight diffs instead of making you hunt for them manually.
See the API docs on the module for more.
lib.rs
:
Analyzing structural differences in Rust values using visitors.
Simple application
This crate provides three functions that you can use immediately without having to learn a bunch of traits.
-
debug_diff
enables you to print the differences between two values of aDiff
type using debug formatting. -
any_difference
andall_different
scan values for differences and return abool
.
You can derive Diff
for any custom type that implements Debug
.
Under the hood
This scheme is modeled after a combination of core::fmt::Formatter
and
serde::Serialize
. There are two main traits:
Diff
is implemented by types that can be diff'd.Differ
is implemented by types that can process differences.
You'll typically derive Diff
. Derived impls will simply present the
structure of the type honestly, much like a derived Debug
impl would.
However, you can also implement it by hand if you need special
functionality.
The most detailed docs are on the Differ
trait.
Visitors
Together, Diff
and Differ
implement the Visitor Pattern for
climbing over a data structure. This is a little different than some other
applications of visitors you might have encountered. In particular:
-
The structure being visited is the Rust notion of types: here is a struct, the struct has fields, etc. A custom impl of
Diff
can fake the internals of a type to abstract away details, but the model is still the same. -
Instead of visiting the parts of a single data structure, here we are visiting two data structures of the same type in parallel. This means we stop visiting if the structures diverge -- for example, if we discover two different variants of an
enum
type. (When this happens we notify theDiffer
through thedifference
method.) -
The double dispatch aspect of the visitor pattern occurs at compile time, rather than at runtime, so there's very little overhead. The description of the pattern on Wikipedia (and the book Design Patterns that originated the name "visitor") doesn't discuss this version, only considering
dyn
-style runtime dispatch.
no_std
support
This crate is no_std
compatible, in case you want to diff data structures
in a deeply-embedded system.
Dependencies
~2.5MB
~57K SLoC