use crate::error::{Result, VectorizerError};
pub mod validation {
use super::*;
pub fn validate_non_empty_string(value: &str, field_name: &str) -> Result<()> {
if value.trim().is_empty() {
return Err(VectorizerError::validation(format!(
"{} cannot be empty",
field_name
)));
}
Ok(())
}
pub fn validate_positive_number(value: f32, field_name: &str) -> Result<()> {
if value.is_nan() {
return Err(VectorizerError::validation(format!(
"{} must be a valid number, got NaN",
field_name
)));
}
if value.is_infinite() {
return Err(VectorizerError::validation(format!(
"{} must be a valid number, got infinity",
field_name
)));
}
if value <= 0.0 {
return Err(VectorizerError::validation(format!(
"{} must be positive, got {}",
field_name, value
)));
}
Ok(())
}
pub fn validate_non_negative_number(value: f32, field_name: &str) -> Result<()> {
if value < 0.0 {
return Err(VectorizerError::validation(format!(
"{} must be non-negative, got {}",
field_name, value
)));
}
Ok(())
}
pub fn validate_collection_name(name: &str) -> Result<()> {
validate_non_empty_string(name, "collection name")?;
if name.contains(' ') {
return Err(VectorizerError::validation(
"Collection name cannot contain spaces",
));
}
if name.contains('/') {
return Err(VectorizerError::validation(
"Collection name cannot contain slashes",
));
}
if name.contains('\\') {
return Err(VectorizerError::validation(
"Collection name cannot contain backslashes",
));
}
if name.contains('@') {
return Err(VectorizerError::validation(
"Collection name cannot contain @ symbols",
));
}
if !name
.chars()
.all(|c| c.is_alphanumeric() || c == '-' || c == '_')
{
return Err(VectorizerError::validation(
"Collection name can only contain alphanumeric characters, hyphens, and underscores",
));
}
Ok(())
}
pub fn validate_vector_id(id: &str) -> Result<()> {
validate_non_empty_string(id, "vector ID")
}
pub fn validate_similarity_metric(metric: &str) -> Result<()> {
match metric {
"cosine" | "euclidean" | "dot_product" => Ok(()),
_ => Err(VectorizerError::validation(format!(
"Invalid similarity metric: {}. Must be: cosine, euclidean, dot_product",
metric
))),
}
}
}
pub mod serialization {
use super::*;
pub fn to_json<T: serde::Serialize>(value: &T) -> Result<String> {
serde_json::to_string(value).map_err(VectorizerError::from)
}
pub fn from_json<T: for<'de> serde::Deserialize<'de>>(json: &str) -> Result<T> {
serde_json::from_str(json).map_err(VectorizerError::from)
}
}