range_check 0.2.0

Rust library with bounds-checking and range helpers.
Documentation
# rust-range-check [![range-check on crates.io]http://meritbadge.herokuapp.com/range-check]https://crates.io/crates/range_check [![Build status]https://travis-ci.org/ogham/rust-range-check.svg?branch=master]https://travis-ci.org/ogham/rust-range-check

This is a little library for early returns with range and bounds checking. It works with Rust’s standard `Range` types.

### [View the Rustdoc]https://docs.rs/range_check


# Installation

This crate works with [Cargo](https://crates.io). Add the following to your `Cargo.toml` dependencies section:

```toml
[dependencies]
range_check = "0.2"
```


# Stability

This crate requires the `collections_range` feature, which was stabilised in Rust 1.28.0.


# Examples

## Range checking in the stdlib

Rust’s standard library allows you to test whether a range contains
a specified value:

```rust
// Range checking with std::ops
assert_eq!((0..24).contains(&23), true);
assert_eq!((0..24).contains(&24), false);
```

For more information, see the
[official Rust documentation for `std::ops::RangeBounds`](https://doc.rust-lang.org/std/ops/trait.RangeBounds.html).


## Range checking with this crate

The `range_check` crate provides the `Check` trait that has a function `check_range`, which returns a `Result` instead of a `bool`.

If the value exists within the range, it will return the value as an `Ok` variant:

```rust
use range_check::Check;

assert_eq!(24680.check_range(1..99999),
           Ok(24680));
```

If the value does _not_ exist within the range, it will be returned inside an `OutOfRangeError` error variant:

```rust
use range_check::Check;

assert_eq!(24680.check_range(1..9999).unwrap_err().to_string(),
           "value (24680) outside of range (1..9999)");
```


## Failing early if a value is outside a range

When testing multiple values, it can sometimes be helpful to automatically return when one of them is outside a range.

In this example, we use the `?` operator to return early:

```rust
use range_check::{Check, OutOfRangeError};

struct Clock {
    hour: i8,
    minute: i8,
}

impl Clock {
    fn new(hour: i8, minute: i8) -> Result<Clock, OutOfRangeError<i8>> {
        Ok(Clock {
            hour: hour.check_range(0..24)?,
            minute: minute.check_range(0..60)?,
        })
    }
}

assert!(Clock::new(23, 59).is_ok());
assert!(Clock::new(23, 60).is_err());
assert!(Clock::new(24, 00).is_err());
```

It becomes a problem when the values being tested are of different types, as there can only be one type as the error `Result` from the function.

As long as the types can be converted using the `From` trait, you can convert the error using the `OutOfRangeError::generify` function. In the first call in this example, we convert the error from containing an `i8` to an `i16`:

```rust
use range_check::{Check, OutOfRangeError};

struct Clock {
    second: i8,
    millisecond: i16,
}

impl Clock {
    fn new(second: i8, millisecond: i16) -> Result<Clock, OutOfRangeError<i16>> {
        Ok(Clock {
            second: second.check_range(0..60).map_err(OutOfRangeError::generify)?,
            millisecond: millisecond.check_range(0..1000)?,
        })
    }
}

assert!(Clock::new(45, 576).is_ok());
assert!(Clock::new(49, 23456).is_err());
assert!(Clock::new(61, 0).is_err());
```