subx_cli/config/
validation.rs

1//! Configuration value validation utilities.
2//!
3//! This module provides comprehensive validation for configuration values,
4//! ensuring type safety and constraint compliance.
5
6use crate::error::{SubXError, SubXResult};
7
8/// Validate a string value against a list of allowed values.
9pub fn validate_enum(value: &str, allowed: &[&str]) -> SubXResult<()> {
10    if allowed.contains(&value) {
11        Ok(())
12    } else {
13        Err(SubXError::config(format!(
14            "Invalid value '{}'. Allowed values: {}",
15            value,
16            allowed.join(", ")
17        )))
18    }
19}
20
21/// Validate a float value within a specified range.
22pub fn validate_float_range(value: &str, min: f32, max: f32) -> SubXResult<f32> {
23    let parsed = value
24        .parse::<f32>()
25        .map_err(|_| SubXError::config(format!("Invalid float value: {}", value)))?;
26    if parsed < min || parsed > max {
27        return Err(SubXError::config(format!(
28            "Value {} is out of range [{}, {}]",
29            parsed, min, max
30        )));
31    }
32    Ok(parsed)
33}
34
35/// Validate an unsigned integer within a specified range.
36pub fn validate_uint_range(value: &str, min: u32, max: u32) -> SubXResult<u32> {
37    let parsed = value
38        .parse::<u32>()
39        .map_err(|_| SubXError::config(format!("Invalid integer value: {}", value)))?;
40    if parsed < min || parsed > max {
41        return Err(SubXError::config(format!(
42            "Value {} is out of range [{}, {}]",
43            parsed, min, max
44        )));
45    }
46    Ok(parsed)
47}
48
49/// Validate a u64 value within a specified range.
50pub fn validate_u64_range(value: &str, min: u64, max: u64) -> SubXResult<u64> {
51    let parsed = value
52        .parse::<u64>()
53        .map_err(|_| SubXError::config(format!("Invalid u64 value: {}", value)))?;
54    if parsed < min || parsed > max {
55        return Err(SubXError::config(format!(
56            "Value {} is out of range [{}, {}]",
57            parsed, min, max
58        )));
59    }
60    Ok(parsed)
61}
62
63/// Validate a usize value within a specified range.
64pub fn validate_usize_range(value: &str, min: usize, max: usize) -> SubXResult<usize> {
65    let parsed = value
66        .parse::<usize>()
67        .map_err(|_| SubXError::config(format!("Invalid usize value: {}", value)))?;
68    if parsed < min || parsed > max {
69        return Err(SubXError::config(format!(
70            "Value {} is out of range [{}, {}]",
71            parsed, min, max
72        )));
73    }
74    Ok(parsed)
75}
76
77/// Validate API key format.
78pub fn validate_api_key(value: &str) -> SubXResult<()> {
79    if value.is_empty() {
80        return Err(SubXError::config("API key cannot be empty".to_string()));
81    }
82    if value.len() < 10 {
83        return Err(SubXError::config("API key is too short".to_string()));
84    }
85    Ok(())
86}
87
88/// Validate URL format.
89pub fn validate_url(value: &str) -> SubXResult<()> {
90    if !value.starts_with("http://") && !value.starts_with("https://") {
91        return Err(SubXError::config(format!(
92            "Invalid URL format: {}. Must start with http:// or https://",
93            value
94        )));
95    }
96    Ok(())
97}
98
99/// Parse boolean value from string.
100pub fn parse_bool(value: &str) -> SubXResult<bool> {
101    match value.to_lowercase().as_str() {
102        "true" | "1" | "yes" | "on" | "enabled" => Ok(true),
103        "false" | "0" | "no" | "off" | "disabled" => Ok(false),
104        _ => Err(SubXError::config(format!(
105            "Invalid boolean value: {}",
106            value
107        ))),
108    }
109}