#![feature(macro_rules)]
#![license = "MIT"]
#![deny(missing_docs)]
#![deny(warnings)]
use std::fmt::{mod, Show};
#[macro_export]
macro_rules! enforce {
($e:expr) => {
::enforce::Enforce {
data: $e,
repr: stringify!($e),
location: (file!(), line!()),
negated: false
}
}
}
#[deriving(PartialEq)]
pub struct Enforce<T: Show> {
#[doc(hidden)]
pub data: T,
#[doc(hidden)]
pub repr: &'static str,
#[doc(hidden)]
pub location: (&'static str, uint),
#[doc(hidden)]
pub negated: bool
}
impl<T: Show> Show for Enforce<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.data)
}
}
impl<T: Show> Enforce<T> {
pub fn to(self) -> Enforce<T> { self }
pub fn bee(self) -> Enforce<T> { self }
pub fn a(self) -> Enforce<T> { self }
pub fn an(self) -> Enforce<T> { self }
pub fn at(self) -> Enforce<T> { self }
pub fn have(self) -> Enforce<T> { self }
pub fn is(self) -> Enforce<T> { self }
pub fn not(mut self) -> Enforce<T> {
self.negated = !self.negated;
self
}
fn error(&self, msg: String) -> ! {
let (file, line) = self.location;
panic!("\nEnforce Error {}:{} - {}", file, line, msg);
}
}
impl<T: PartialEq + Show> Enforce<T> {
pub fn equal(self, val: T) {
if self.negated {
if self.data == val && val == self.data {
self.error(format!("{} == {}", self.repr, val));
}
} else {
if self.data != val || val != self.data {
self.error(format!("{} != {}", self.repr, val));
}
}
}
pub fn same(self, val: T) { self.equal(val) }
pub fn eql(self, val: T) { self.equal(val) }
pub fn equivalent(self, val: T) { self.equal(val) }
}
impl<T: Show> Enforce<Option<T>> {
pub fn some(mut self) {
if self.negated { self.negated = false; return self.none(); }
if !self.data.is_some() {
self.error(format!("{} is None", self.repr));
}
}
pub fn none(mut self) {
if self.negated { self.negated = false; self.some(); return; }
if !self.data.is_none() {
self.error(format!("{} is {}", self.repr, self.data));
}
}
}
impl<S: Show, E: Show> Enforce<Result<S, E>> {
pub fn ok(mut self) {
if self.negated { self.negated = false; return self.err(); }
if !self.data.is_ok() {
self.error(format!("{} is {}", self.repr, self.data));
}
}
pub fn err(mut self) {
if self.negated { self.negated = false; return self.ok(); }
if !self.data.is_err() {
self.error(format!("{} is {}", self.repr, self.data));
}
}
}