adhesion 0.5.0

A set of macros for design by contact in Rust. The design of this library was inspired by D's contract programming facilities.
Documentation
# Adhesion

[![Linux build status](https://travis-ci.org/ErichDonGubler/adhesion-rs.svg)](https://travis-ci.org/ErichDonGubler/adhesion-rs)
[![Windows build status](https://ci.appveyor.com/api/projects/status/github/ErichDonGubler/adhesion-rs?svg=true)](https://ci.appveyor.com/project/ErichDonGubler/adhesion-rs)
[![crates.io latest published version](https://img.shields.io/crates/v/adhesion.svg)](https://crates.io/crates/adhesion)
[![docs.rs latest published version](https://docs.rs/adhesion/badge.svg)](https://docs.rs/adhesion)

A set of macros for [design by contact](https://en.wikipedia.org/wiki/Design_by_contract)
in Rust. The design of this library was inspired by [D's contract programming
facilities](https://tour.dlang.org/tour/en/gems/contract-programming).
Here's a quick example:

```rust,skt-main
use std::i32;

contract! {
    fn add_one_to_odd(x: i32) -> i32 {
        post(y) {
            assert!(y - 1 == x, "reverse operation did not produce input");
        }
        body {
            x + 1
        }
        pre {
            assert!(x != i32::MAX, "cannot add one to input at max of number range");
            assert!(x % 2 != 0, "evens ain't appropriate here");
        }
    }
}

assert!(add_one_to_odd(3) == 4);
assert!(add_one_to_odd(5) == 6);
assert_that!(add_one_to_odd(2), panics);
assert_that!(add_one_to_odd(i32::MAX), panics);
```

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
checks with the `double_check` block, which will be checked before **and**
after `body` has run:

```rust,should_panic,skt-main
struct Counter {
    count: u32,
    max: u32
}

contract! {
    fn increment_counter(c: &mut Counter) {
        double_check {
            assert!(c.count <= c.max, "counter max has been exceeded");
        }
        body {
            c.count += 1;
        }
    }
}

let mut counter = Counter { count: 0, max: 3 };

macro_rules! assert_incremented_eq {
    ($e: expr) => ({
        increment_counter(&mut counter);
        assert!(counter.count == $e, format!("expected counter to be {}, got {}", $e, counter.count));
    })
}

assert_incremented_eq!(1);
assert_incremented_eq!(2);
assert_incremented_eq!(3);
assert_incremented_eq!(4); // panics!
```

Actually, the above example can use a top-level `double_check` block inside of
an `impl` block instead, so that invariants can be maintained for each method
without needing to duplicate code:

```rust,should_panic,skt-main
struct Counter {
    count: u32,
    max: u32
}

impl Counter {
    contract! {
        double_check {
            assert!(self.count <= self.max, "counter max has been exceeded");
        }

        fn increment(&mut self) {
            body {
                self.count.checked_add();
            }
        }
    }

}

let mut counter = Counter { count: 0, max: 3 };

macro_rules! assert_incremented_eq {
    ($e: expr) => ({
        counter.increment();
        assert!(counter.count == $e, format!("expected counter to be {}, got {}", $e, counter.count));
    })
}

assert_incremented_eq!(1);
assert_incremented_eq!(2);
assert_incremented_eq!(3);
assert_incremented_eq!(4); // panics!
```

Nifty, right? Check out [the docs](https://docs.rs/adhesion) if you want more
detail about this crate and what you can do with it.

## FAQ

### 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!

### Why has D's `invariant` been renamed to `double_check`?

After the v0.2.0 release, @eternaleye pointed out in this [Reddit thread](https://www.reddit.com/r/rust/comments/6ooinu/adhesionrs_v020_contract_programming_in_rust_with/dkjd3kc/)
that technically an "invariant" connotes a strong guarantee that must be
rigorously maintained between ALL operations in code. This sort of guarantee is
NOT provided by the behavior D's `invariant` block, as demonstrated by [the
link](http://hackingdistributed.com/2016/07/13/reentrancy-woes/) that
@eternaleye provided.

Semantics are important, especially in systems that attempt to introduce more
rigor to software development like design by contract. For this reason, the
combined pre- and post-check block that D calls `invariant` is called
`double_check` in this library.

## Licensing

This project is dual-licensed under your choice of the [MIT license](/LICENSE-MIT)
or the [Apache 2.0 license](/LICENSE-APACHE-2.0).

* Adhesion uses a modified version of components from the [rust-parse-generics]https://github.com/DanielKeep/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.
* @eternaleye, for bringing some security expertise to bear and motivating
    the `double_check` divergence from D's `invariant`.