must 0.2.0

assertion library for rust
Documentation
use std;
use std::fmt::{self, Debug, Display, Formatter};

#[derive(Debug)]
pub struct Error {
	/// Dumped using debug trait.
	pub got: String,
	pub kind: ErrorKind,
}


/// Common prefix: (so do not incude it in separate message)
///
/// {} must
///
///
///
#[derive(Debug)]
pub enum ErrorKind {
	MustEq { to: String },
	MustNotEq { to: String },
	MustBeOk,
	MustBeErr,
	MustBeSome,
	MustBeNone,
	MustHaveLength { len: usize },
	MustBeEmpty,
	MustBeInRange { range: String },
	MustNotBeInRange { range: String },
	MustBeLowercase,
	MustBeUppercase,
	MustBeAscii,
	MustBeEqAsciiIgnoreCase { to: String },
	MustBeLessThan { other: String },
	MustBeLessThanOrEqual { other: String },
	MustBeGreaterThan { other: String },
	MustBeGreaterThanOrEqual { other: String },
	MustBeNan,
	MustNotBeNan,

	Msg(String),
	Error(Box<std::error::Error>),
}

impl Display for ErrorKind {
	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
		use self::ErrorKind::*;
		match self {
			&MustEq { ref to } => write!(f, "must be {}", to),
			&MustNotEq { ref to } => write!(f, "must not be {}", to),
			&MustBeOk => write!(f, "must be ok"),
			&MustBeErr => write!(f, "must be err"),
			&MustBeSome => write!(f, "must be some"),
			&MustBeNone => write!(f, "must be none"),
			&MustHaveLength { len } => write!(f, "must have length {}", len),
			&MustBeEmpty => write!(f, "must be empty"),
			&MustBeInRange { ref range } => write!(f, "must be in range {}", range),
			&MustNotBeInRange { ref range } => write!(f, "must not be in range {}", range),
			&MustBeLowercase => write!(f, "must be lowercase"),
			&MustBeUppercase => write!(f, "must be uppercase"),
			&MustBeAscii => write!(f, "must be ascii"),
			&MustBeEqAsciiIgnoreCase { ref to } => write!(f, "must eq ignore ascii case {}", to),
			&MustBeLessThan { ref other } => write!(f, "must be less than {}", other),
			&MustBeLessThanOrEqual { ref other } => {
				write!(f, "must be less than or equal {}", other)
			}
			&MustBeGreaterThan { ref other } => write!(f, "must be greater than {}", other),
			&MustBeGreaterThanOrEqual { ref other } => {
				write!(f, "must be greater than or equal to {}", other)
			}
			&MustBeNan => write!(f, "must be NAN"),
			&MustNotBeNan => write!(f, "must not be NAN"),

			&Msg(ref msg) => write!(f, "{}", msg),

			// TODO(kdy): cause chain
			&Error(ref err) => write!(f, "{}", err.description()),
		}
	}
}

/// shortcut for
/// format!("{:?}", t)
pub fn dump<T: Debug>(t: T) -> String {
	format!("{:?}", t)
}



/// Used from [ErrorKind.but_got][].
///
/// [ErrorKind.but_got]:enum.ErrorKind.html#method.but_got
pub trait FromError {
	fn from_err(err: ErrorKind, got: String) -> Self;
}

impl ErrorKind {
	pub fn but_got<T: Debug, R: FromError>(self, got: T) -> R {
		R::from_err(self, dump(got))
	}
}

impl<O: Debug> FromError for Result<O, Error> {
	fn from_err(err: ErrorKind, got: String) -> Self {
		Err(Error {
			got: got,
			kind: err,
		})
	}
}