validate 0.6.0

A library to easily validate user input
Documentation
use std::ops::Add;

#[derive(Debug, PartialEq)]
pub struct Error {
	message: String
}

impl Error {
	pub fn get_message(&self) -> String {
		self.message.clone()
	}
}

impl<S: Into<String>> From<S> for Error {
	fn from(msg: S) -> Self {
		Error { message: msg.into() }
	}
}


pub type ValidationResult = Result<(), Error>;

pub struct Rule<T: ? Sized> {
	rule: Box<Fn(&T) -> ValidationResult>
}

impl<T: 'static> Rule<T> {
	pub fn map<'b, F, U>(self, get: F) -> Rule<U>
		where F: Fn(&U) -> T + 'static,
		      U: ? Sized + 'static {
		Rule::from(move |input: &U| {
			let mapped_input = get(input);
			self.validate(&mapped_input)
		})
	}
}

impl<T: ? Sized + 'static> Rule<T> {
	pub fn validate(&self, input: &T) -> ValidationResult {
		(*self.rule)(input)
	}

	pub fn nest<'b, R, F, U>(get: F, rule: R) -> Self
		where
				R: Into<Rule<U>>,
				F: Fn(&T) -> &U + 'static,
				U: ? Sized + 'static {
		let converted_rule = rule.into();
		Rule::from(move |input: &T| {
			let mapped_input = get(input);
			converted_rule.validate(&mapped_input)
		})
	}


	pub fn name(self, name: &str) -> Self {
		let name = name.to_owned();
		Rule::from(move |input: &T| {
			self.validate(&input).map_err(|err: Error| {
				(name.clone() + " " + &err.get_message()).into()
			})
		})
	}
}

impl<T, F> From<F> for Rule<T>
	where F: Fn(&T) -> ValidationResult + 'static,
	      T: ? Sized {
	fn from(func: F) -> Self {
		Rule {
			rule: Box::new(func)
		}
	}
}

impl<T: ? Sized + 'static, R: Into<Rule<T>>> Add<R> for Rule<T> {
	type Output = Rule<T>;

	fn add(self, rule: R) -> Self::Output {
		let rule = rule.into();
		Rule::from(move |input: &T| {
			self.validate(input)?;
			rule.validate(input)
		})
	}
}