Module smart_config::validation
source · Expand description
Parameter and config validation and filtering.
§Overview
The core validation functionality is encapsulated in the Validate
trait.
§Examples
§Validation
use secrecy::{ExposeSecret, SecretString};
use smart_config::validation;
#[derive(DescribeConfig, DeserializeConfig)]
#[config(validate(
Self::validate_secret_key,
"secret key must have expected length"
))]
struct ValidatedConfig {
secret_key: SecretString,
/// Reference key length. If specified, the secret key length
/// will be checked against it.
#[config(validate(..=100))]
// ^ Validates that the value is in the range. Note that validations
// handle `Option`s intelligently; if the value isn't specified
// (i.e., is `None`), it will pass validation.
secret_key_len: Option<usize>,
#[config(validate(not_empty, "must not be empty"))]
app_name: String,
}
// We have to use `&String` rather than more idiomatic `&str` in order to
// exactly match the validated type.
fn not_empty(s: &String) -> bool {
!s.is_empty()
}
impl ValidatedConfig {
fn validate_secret_key(&self) -> Result<(), ErrorWithOrigin> {
if let Some(expected_len) = self.secret_key_len {
let actual_len = self.secret_key.expose_secret().len();
if expected_len != actual_len {
return Err(ErrorWithOrigin::custom(format!(
"unexpected `secret_key` length ({actual_len}); \
expected {expected_len}"
)));
}
}
Ok(())
}
}
§Filtering
Filtering reuses the Validate
trait, but rather than failing, converts a value to None
.
use smart_config::validation;
#[derive(DescribeConfig, DeserializeConfig)]
struct FilteringConfig {
/// Will convert `url: ''` to `None`.
#[config(deserialize_if(validation::NotEmpty))]
url: Option<String>,
/// Will convert either of `env: ''` or `env: 'unset'` to `None`.
#[config(deserialize_if(valid_env, "not empty or 'unset'"))]
env: Option<String>,
}
fn valid_env(s: &String) -> bool {
!s.is_empty() && s != "unset"
}
// Base case: no filtering.
let env = smart_config::Environment::from_iter("", [
("URL", "https://example.com"),
("ENV", "prod"),
]);
let config: FilteringConfig = testing::test_complete(env)?;
assert_eq!(config.url.unwrap(), "https://example.com");
assert_eq!(config.env.unwrap(), "prod");
// Filtering applied to both params.
let env = smart_config::Environment::from_iter("", [
("URL", ""),
("ENV", "unset"),
]);
let config: FilteringConfig = testing::test_complete(env)?;
assert_eq!(config.url, None);
assert_eq!(config.env, None);
Structs§
- Validates that a string or a data collection (e.g.,
Vec
) is not empty.
Traits§
- Generic post-validation for a configuration parameter or a config.