apollo-configuration 0.4.0

A typed, friendly configuration system for Apollo products.
Documentation
use apollo_configuration::configuration;
use apollo_configuration::parse_yaml;
use apollo_configuration::types::{SocketAddr, SocketAddrV4, SocketAddrV6};
use serde::{Deserialize, Serialize};

#[configuration]
struct SocketConfig {
    #[config(required)]
    address: SocketAddr,
    #[config(required)]
    v4_address: SocketAddrV4,
    #[config(required)]
    v6_address: SocketAddrV6,
}

#[test]
fn socket_addresses_parse() {
    let config: SocketConfig = parse_yaml(
        r#"
        address: 192.168.1.1:8080
        v4_address: 10.0.0.1:3000
        v6_address: "[2001:db8::1]:443"
        "#,
        &Default::default(),
    )
    .unwrap();

    assert_eq!(
        *config.address,
        "192.168.1.1:8080".parse::<std::net::SocketAddr>().unwrap()
    );
    assert_eq!(
        *config.v4_address,
        "10.0.0.1:3000".parse::<std::net::SocketAddrV4>().unwrap()
    );
    assert_eq!(
        *config.v6_address,
        "[2001:db8::1]:443"
            .parse::<std::net::SocketAddrV6>()
            .unwrap()
    );
}

#[test]
fn socket_address_error_message() {
    let result = parse_yaml::<SocketConfig>(
        r#"
        address: not-a-socket
        v4_address: 10.0.0.1:3000
        v6_address: "[::1]:443"
        "#,
        &Default::default(),
    );
    let err = result.expect_err("should fail to parse invalid socket address");
    assert_eq!(
        format!("{err}"),
        "failed to parse value: invalid socket address syntax"
    );
}

#[derive(Debug, Deserialize, Serialize)]
struct SerializableSocketConfig {
    socket: SocketAddr,
    socket_v4: SocketAddrV4,
    socket_v6: SocketAddrV6,
}

#[test]
fn socket_addr_serializes() {
    let config: SerializableSocketConfig = serde_yaml::from_str(
        r#"
        socket: 192.168.1.1:8080
        socket_v4: 10.0.0.1:3000
        socket_v6: "[2001:db8::1]:443"
        "#,
    )
    .unwrap();
    let yaml = serde_yaml::to_string(&config).unwrap();
    insta::assert_snapshot!(yaml, @r"
    socket: 192.168.1.1:8080
    socket_v4: 10.0.0.1:3000
    socket_v6: '[2001:db8::1]:443'
    ");
}