Adhesion
A set of macros for design by contact in Rust. The design of this library was inspired by D's contract programming facilities. Here's a quick example:
use i32;
contract!
assert!;
assert!;
assert_that!;
assert_that!;
In the above example, pre
runs before body
, and post
, which has the return value of this function bound to y
, runs after. We can also define invariants with the invariant
block, which will be checked before and after body
has run:
contract!
let mut counter = Counter ;
assert_incremented_eq!;
assert_incremented_eq!;
assert_incremented_eq!;
assert_incremented_eq!; // panics!
When every contract block is being utilized, the order of the checks inserted into the contract definition are as follows:
pre
invariant
body
invariant
post
More examples can be found in:
- The examples directory
- The test suite for this library
Current Limitations
The only major known limitation at the time of writing is the inability to use more than a single function inside a single contract!
block (issue here). This limitation is planned to be lifted.
Why "Adhesion"?
This library is called "Adhesion" in reference to a particular type of contract called a "contract of adhesion", also known as a "take-it-or-leave-it" contract. Assertions in programming are definitely "take it or leave it" -- if an assertion is failing, you either have to fix the conditions of the assertion, or change the assertion itself. It sounded appropriate!
Licensing
This project is dual-licensed under your choice of the MIT license or the Apache 2.0 license.
- Adhesion uses a modified version of components from the rust-parse-generics project. Both the original and modified versions here use the same dual license as this project.
Contributors
- @ErichDonGubler, original author
- @dzamlo, for providing assistance with various important features.
- @DanielKeep, for his incredible help making it possible for generics to be parsed and used in macros generally, and for his mentoring during Adhesion's development of its features involving generics.