vectorizer_rust_sdk/
utils.rs

1//! Essential utilities for the Vectorizer SDK
2
3use crate::error::{VectorizerError, Result};
4
5/// Input validation
6pub mod validation {
7    use super::*;
8
9    /// Validate that a string is not empty
10    pub fn validate_non_empty_string(value: &str, field_name: &str) -> Result<()> {
11        if value.trim().is_empty() {
12            return Err(VectorizerError::validation(format!(
13                "{} cannot be empty",
14                field_name
15            )));
16        }
17        Ok(())
18    }
19
20    /// Validate that a number is positive
21    pub fn validate_positive_number(value: f32, field_name: &str) -> Result<()> {
22        if value.is_nan() {
23            return Err(VectorizerError::validation(format!(
24                "{} must be a valid number, got NaN",
25                field_name
26            )));
27        }
28        if value.is_infinite() {
29            return Err(VectorizerError::validation(format!(
30                "{} must be a valid number, got infinity",
31                field_name
32            )));
33        }
34        if value <= 0.0 {
35            return Err(VectorizerError::validation(format!(
36                "{} must be positive, got {}",
37                field_name, value
38            )));
39        }
40        Ok(())
41    }
42
43    /// Validate that a number is non-negative
44    pub fn validate_non_negative_number(value: f32, field_name: &str) -> Result<()> {
45        if value < 0.0 {
46            return Err(VectorizerError::validation(format!(
47                "{} must be non-negative, got {}",
48                field_name, value
49            )));
50        }
51        Ok(())
52    }
53
54    /// Validate collection name
55    pub fn validate_collection_name(name: &str) -> Result<()> {
56        validate_non_empty_string(name, "collection name")?;
57        
58        // Check for specific invalid characters first (for specific error messages)
59        if name.contains(' ') {
60            return Err(VectorizerError::validation(
61                "Collection name cannot contain spaces"
62            ));
63        }
64        if name.contains('/') {
65            return Err(VectorizerError::validation(
66                "Collection name cannot contain slashes"
67            ));
68        }
69        if name.contains('\\') {
70            return Err(VectorizerError::validation(
71                "Collection name cannot contain backslashes"
72            ));
73        }
74        if name.contains('@') {
75            return Err(VectorizerError::validation(
76                "Collection name cannot contain @ symbols"
77            ));
78        }
79        
80        // Only allow alphanumeric characters, hyphens, and underscores
81        if !name.chars().all(|c| c.is_alphanumeric() || c == '-' || c == '_') {
82            return Err(VectorizerError::validation(
83                "Collection name can only contain alphanumeric characters, hyphens, and underscores"
84            ));
85        }
86        
87        Ok(())
88    }
89
90    /// Validate vector ID
91    pub fn validate_vector_id(id: &str) -> Result<()> {
92        validate_non_empty_string(id, "vector ID")
93    }
94
95    /// Validate similarity metric
96    pub fn validate_similarity_metric(metric: &str) -> Result<()> {
97        match metric {
98            "cosine" | "euclidean" | "dot_product" => Ok(()),
99            _ => Err(VectorizerError::validation(format!(
100                "Invalid similarity metric: {}. Must be: cosine, euclidean, dot_product",
101                metric
102            ))),
103        }
104    }
105}
106
107/// Serialization utilities
108pub mod serialization {
109    use super::*;
110
111    /// Serialize value to JSON
112    pub fn to_json<T: serde::Serialize>(value: &T) -> Result<String> {
113        serde_json::to_string(value).map_err(VectorizerError::from)
114    }
115
116    /// Deserialize JSON to value
117    pub fn from_json<T: for<'de> serde::Deserialize<'de>>(json: &str) -> Result<T> {
118        serde_json::from_str(json).map_err(VectorizerError::from)
119    }
120}