1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! This is a little library that helps with range and bounds checking. It works
//! with Rust’s standard `Range` types.
//!
//!
//! Range checking in the stdlib
//! ----------------------------
//!
//! Rust’s standard library allows you to test whether a range contains
//! a specified value:
//!
//! ```
//! // 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.Check.html) trait that has a function
//! `check_range`, which returns a [`Result`](type.Result.html) instead of a `bool`.
//!
//! If the value exists within the range, it will return the value as an
//! `Ok` variant:
//!
//! ```
//! 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`](struct.OutOfRangeError.html) error variant:
//!
//! ```
//! 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:
//!
//! ```
//! 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`](https://doc.rust-lang.org/std/convert/trait.From.html)
//! trait, you can convert the error using the
//! [`OutOfRangeError::generify`](struct.OutOfRangeError.html#method.generify)
//! function. In the first call in this example, we convert the error from
//! containing an `i8` to an `i16`:
//!
//! ```
//! 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());
//! ```
pub use ;