pub mod types;
pub use types::{Collective, CollectiveStats};
use crate::error::{PulseDBError, ValidationError};
pub const MAX_COLLECTIVE_NAME_LENGTH: usize = 255;
pub(crate) fn validate_collective_name(name: &str) -> Result<(), PulseDBError> {
if name.is_empty() {
return Err(ValidationError::required_field("name").into());
}
if name.trim().is_empty() {
return Err(ValidationError::invalid_field("name", "must not be only whitespace").into());
}
if name.len() > MAX_COLLECTIVE_NAME_LENGTH {
return Err(ValidationError::invalid_field(
"name",
format!(
"must not exceed {} characters (got {})",
MAX_COLLECTIVE_NAME_LENGTH,
name.len()
),
)
.into());
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_collective_name_valid() {
assert!(validate_collective_name("my-project").is_ok());
assert!(validate_collective_name("a").is_ok());
assert!(validate_collective_name("Project with spaces").is_ok());
}
#[test]
fn test_validate_collective_name_empty() {
let err = validate_collective_name("").unwrap_err();
assert!(err.is_validation());
}
#[test]
fn test_validate_collective_name_whitespace_only() {
let err = validate_collective_name(" ").unwrap_err();
assert!(err.is_validation());
}
#[test]
fn test_validate_collective_name_too_long() {
let long_name = "x".repeat(256);
let err = validate_collective_name(&long_name).unwrap_err();
assert!(err.is_validation());
}
#[test]
fn test_validate_collective_name_exactly_max_length() {
let name = "x".repeat(MAX_COLLECTIVE_NAME_LENGTH);
assert!(validate_collective_name(&name).is_ok());
}
}