toon_format/utils/
validation.rs

1use serde_json::Value;
2
3use crate::types::{
4    ToonError,
5    ToonResult,
6};
7
8/// Validate that nesting depth doesn't exceed the maximum.
9pub fn validate_depth(depth: usize, max_depth: usize) -> ToonResult<()> {
10    if depth > max_depth {
11        return Err(ToonError::InvalidStructure(
12            "Maximum nesting depth of {max_depth} exceeded".to_string(),
13        ));
14    }
15    Ok(())
16}
17
18/// Validate that a field name is not empty.
19pub fn validate_field_name(name: &str) -> ToonResult<()> {
20    if name.is_empty() {
21        return Err(ToonError::InvalidInput(
22            "Field name cannot be empty".to_string(),
23        ));
24    }
25    Ok(())
26}
27
28/// Recursively validate a JSON value and all nested fields.
29pub fn validate_value(value: &Value) -> ToonResult<()> {
30    match value {
31        Value::Object(obj) => {
32            for (key, val) in obj {
33                validate_field_name(key)?;
34                validate_value(val)?;
35            }
36        }
37        Value::Array(arr) => {
38            for val in arr {
39                validate_value(val)?;
40            }
41        }
42        _ => {}
43    }
44    Ok(())
45}
46
47#[cfg(test)]
48mod tests {
49    use serde_json::json;
50
51    use super::*;
52
53    #[test]
54    fn test_validate_depth() {
55        assert!(validate_depth(0, 10).is_ok());
56        assert!(validate_depth(5, 10).is_ok());
57        assert!(validate_depth(10, 10).is_ok());
58        assert!(validate_depth(11, 10).is_err());
59    }
60
61    #[test]
62    fn test_validate_field_name() {
63        assert!(validate_field_name("name").is_ok());
64        assert!(validate_field_name("user_id").is_ok());
65        assert!(validate_field_name("").is_err());
66    }
67
68    #[test]
69    fn test_validate_value() {
70        assert!(validate_value(&json!(null)).is_ok());
71        assert!(validate_value(&json!(123)).is_ok());
72        assert!(validate_value(&json!("hello")).is_ok());
73        assert!(validate_value(&json!({"name": "Alice"})).is_ok());
74        assert!(validate_value(&json!([1, 2, 3])).is_ok());
75
76        let bad_obj = json!({"": "value"});
77        assert!(validate_value(&bad_obj).is_err());
78    }
79}