use super::error::{
ArgumentError,
ArgumentResult,
};
pub trait OptionArgument<T> {
fn require_non_null(self, name: &str) -> ArgumentResult<T>;
fn require_non_null_and<F>(
self,
name: &str,
predicate: F,
error_msg: &str,
) -> ArgumentResult<T>
where
F: FnOnce(&T) -> bool;
fn validate_if_present<F>(self, name: &str, validator: F) -> ArgumentResult<Option<T>>
where
F: FnOnce(&T) -> ArgumentResult<T>;
}
impl<T> OptionArgument<T> for Option<T> {
#[inline]
fn require_non_null(self, name: &str) -> ArgumentResult<T> {
match self {
Some(value) => Ok(value),
None => {
let message = format!("Parameter '{}' cannot be null", name);
Err(ArgumentError::new(message))
}
}
}
#[inline]
fn require_non_null_and<F>(self, name: &str, predicate: F, error_msg: &str) -> ArgumentResult<T>
where
F: FnOnce(&T) -> bool,
{
match self {
Some(value) => {
if predicate(&value) {
Ok(value)
} else {
let message = format!("Parameter '{}' {}", name, error_msg);
Err(ArgumentError::new(message))
}
}
None => {
let message = format!("Parameter '{}' cannot be null", name);
Err(ArgumentError::new(message))
}
}
}
#[inline]
fn validate_if_present<F>(self, _name: &str, validator: F) -> ArgumentResult<Option<T>>
where
F: FnOnce(&T) -> ArgumentResult<T>,
{
match self {
None => Ok(None),
Some(ref value) => match validator(value) {
Ok(_) => Ok(self),
Err(e) => Err(e),
},
}
}
}
#[inline]
pub fn require_null_or<T, F>(
name: &str,
value: Option<T>,
predicate: F,
error_msg: &str,
) -> ArgumentResult<Option<T>>
where
F: FnOnce(&T) -> bool,
{
match value {
None => Ok(None),
Some(ref v) => {
if !predicate(v) {
return Err(ArgumentError::new(format!(
"Parameter '{}' {}",
name, error_msg
)));
}
Ok(value)
}
}
}