apollo-configuration 0.4.0

A typed, friendly configuration system for Apollo products.
Documentation
use std::time::Duration as StdDuration;

use apollo_configuration::configuration;
use apollo_configuration::parse_yaml;
use apollo_configuration::types::Duration;
use serde::{Deserialize, Serialize};

#[configuration]
struct DurationConfig {
    #[config(required)]
    timeout: Duration,
}

#[test]
fn duration_parses() {
    let config: DurationConfig = parse_yaml("timeout: 30s", &Default::default()).unwrap();
    assert_eq!(*config.timeout, StdDuration::from_secs(30));

    let config: DurationConfig = parse_yaml("timeout: 5m", &Default::default()).unwrap();
    assert_eq!(*config.timeout, StdDuration::from_secs(300));

    let config: DurationConfig = parse_yaml("timeout: 1h30m", &Default::default()).unwrap();
    assert_eq!(*config.timeout, StdDuration::from_secs(5400));

    let config: DurationConfig = parse_yaml("timeout: 100ms", &Default::default()).unwrap();
    assert_eq!(*config.timeout, StdDuration::from_millis(100));
}

#[test]
fn duration_error_message() {
    let result = parse_yaml::<DurationConfig>("timeout: badvalue", &Default::default());
    let err = result.expect_err("should reject invalid duration");
    assert_eq!(
        format!("{err}"),
        "failed to parse value: expected number at 0"
    );
}

#[derive(Debug, Deserialize, Serialize)]
struct SerializableDurationConfig {
    duration: Duration,
}

#[test]
fn duration_serializes() {
    let config: SerializableDurationConfig = serde_yaml::from_str("duration: 1h30m").unwrap();
    let yaml = serde_yaml::to_string(&config).unwrap();
    insta::assert_snapshot!(yaml, @"duration: 1h 30m");
}