use super::error::{
ArgumentError,
ArgumentResult,
};
pub trait CollectionArgument {
fn require_non_empty(&self, name: &str) -> ArgumentResult<&Self>;
fn require_length_be(&self, name: &str, length: usize) -> ArgumentResult<&Self>;
fn require_length_at_least(&self, name: &str, min_length: usize) -> ArgumentResult<&Self>;
fn require_length_at_most(&self, name: &str, max_length: usize) -> ArgumentResult<&Self>;
fn require_length_in_range(
&self,
name: &str,
min_length: usize,
max_length: usize,
) -> ArgumentResult<&Self>;
}
impl<T> CollectionArgument for [T] {
fn require_non_empty(&self, name: &str) -> ArgumentResult<&Self> {
if self.is_empty() {
return Err(ArgumentError::new(format!(
"Collection '{}' cannot be empty",
name
)));
}
Ok(self)
}
fn require_length_be(&self, name: &str, length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length != length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be {} but was {}",
name, length, actual_length
)));
}
Ok(self)
}
fn require_length_at_least(&self, name: &str, min_length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length < min_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be at least {} but was {}",
name, min_length, actual_length
)));
}
Ok(self)
}
fn require_length_at_most(&self, name: &str, max_length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length > max_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be at most {} but was {}",
name, max_length, actual_length
)));
}
Ok(self)
}
fn require_length_in_range(
&self,
name: &str,
min_length: usize,
max_length: usize,
) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length < min_length || actual_length > max_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be in range [{}, {}] but was {}",
name, min_length, max_length, actual_length
)));
}
Ok(self)
}
}
impl<T> CollectionArgument for Vec<T> {
fn require_non_empty(&self, name: &str) -> ArgumentResult<&Self> {
if self.is_empty() {
return Err(ArgumentError::new(format!(
"Collection '{}' cannot be empty",
name
)));
}
Ok(self)
}
fn require_length_be(&self, name: &str, length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length != length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be {} but was {}",
name, length, actual_length
)));
}
Ok(self)
}
fn require_length_at_least(&self, name: &str, min_length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length < min_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be at least {} but was {}",
name, min_length, actual_length
)));
}
Ok(self)
}
fn require_length_at_most(&self, name: &str, max_length: usize) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length > max_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be at most {} but was {}",
name, max_length, actual_length
)));
}
Ok(self)
}
fn require_length_in_range(
&self,
name: &str,
min_length: usize,
max_length: usize,
) -> ArgumentResult<&Self> {
let actual_length = self.len();
if actual_length < min_length || actual_length > max_length {
return Err(ArgumentError::new(format!(
"Collection '{}' length must be in range [{}, {}] but was {}",
name, min_length, max_length, actual_length
)));
}
Ok(self)
}
}
pub fn require_element_non_null<T>(name: &str, collection: &[Option<T>]) -> ArgumentResult<()> {
for (index, item) in collection.iter().enumerate() {
if item.is_none() {
return Err(ArgumentError::new(format!(
"Collection '{}': element at index {} cannot be null",
name, index
)));
}
}
Ok(())
}