rep
rep
is a tiny utility that lets you easily enforce representation/class invariants throughout your Rust data structures.
Representation invariants are logical assertions that must hold true for every mutation of your data structure. For example, in your GIS application, you may have the following rep invariant for a LatLong
.
self.lat >= -90.0 && self.lat <= 90 && self.long >= -180.0 && self.long <= 180
Enforcing representation invariants is easy with rep
. Adding invariants to your data structures is just 2 easy steps.
- Define a correct representation (by implementing
CheckRep
either manually or with a macro) - Insert runtime checks (either manually or with a macro)
some examples
We can start off with a simple data structure.
use *;
The CheckRep
trait can be implemented. This serves as a definition of correct representation.
Now we can use the #[check_rep]
macro to automatically insert calls to check_rep
at start and end of all methods that are pub
and mutate &mut self
. We can also manually make calls to check_rep
wherever we so desire.
// <-- this inserts calls to check_rep at start and end of move_by
some more examples
For simple representations, we can even derive an implementation of CheckRep
.
We can recursively check representation and use custom functions per field.
More advanced rep-checking can be done through custom checking.
Once CheckRep
is implemented, you may use it with the #[check_rep
, #[require_rep
, and #[check_rep
macros.
// this adds `check_rep` at start and end of all public mutating methods
If a logger is present invariant violation will be logged instead of panicked.
usage
Just add the following to your Cargo.toml
file.
[]
= "0.3.0"
Then, in your module.
use *;