must 0.2.0

assertion library for rust
Documentation
use errors::{ErrorKind, dump};
use lazy::SimpleAssert;
use marker::RangeArgument;
use std::fmt::Debug;


pub trait MustBeInRange<R: Debug + RangeArgument<Self>>
    : Copy + Sized + Debug + PartialOrd {
	///
	/// ```rust
	/// #[macro_use] extern crate must;
	/// use must::prelude::*;
	/// # fn main() {
	/// 10.must_be_in_range(10..);
	/// 650.must_be_in_range(600..700);
	/// 218.must_be_in_range(..);
	/// 1.must_be_in_range(1..);
	/// # }
	/// ```
	fn must_be_in_range(self, range: R) -> SimpleAssert<Self> {
		if is_in_range(self, &range) {
			self.into()
		} else {
			ErrorKind::MustBeInRange { range: dump(&range) }.but_got(self)
		}
	}

	///
	/// ```rust
	/// #[macro_use] extern crate must;
	/// use must::prelude::*;
	/// # fn main() {
	/// 10.must_not_be_in_range(..10);
	/// # }
	/// ```
	fn must_not_be_in_range(self, range: R) -> SimpleAssert<Self> {
		if !is_in_range(self, &range) {
			self.into()
		} else {
			ErrorKind::MustNotBeInRange { range: dump(&range) }.but_got(self)
		}
	}
}

impl<V, R> MustBeInRange<R> for V
	where V: Copy + Sized + Debug + PartialOrd,
	      R: Debug + RangeArgument<V>
{
}


fn is_in_range<I, R>(item: I, range: &R) -> bool
	where I: Debug + Copy + PartialOrd,
	      R: Debug + RangeArgument<I>
{
	if let Some(start) = range.start() {
		if item < *start {
			return false;
		}
	}
	if let Some(end) = range.end() {
		// end is exclusive
		if item >= *end {
			return false;
		}
	}

	true
}

#[test]
fn test_is_in_range() {
	assert_eq!(true, is_in_range(1, &(1..)), "1 is in [1, _)");
	assert_eq!(true, is_in_range(1, &(..10)), "1 is in [_, 10)");
	assert_eq!(true, is_in_range(1, &(..)), "1 is in [_, _)");
	assert_eq!(false, is_in_range(10, &(..10)), "10 is not in [_, 10)");
}

fn _assert() {
	fn in_range<T: MustBeInRange<R>, R: Debug + RangeArgument<T>>() {}

	use std::ops::{Range, RangeFrom, RangeFull, RangeTo};
	in_range::<i32, Range<i32>>();
	in_range::<i32, RangeTo<i32>>();
	in_range::<i32, RangeFull>();
	in_range::<i32, RangeFrom<i32>>();
	in_range::<u64, Range<u64>>();
}