apollo-configuration-macros 0.1.1

Supporting macros for apollo-configuration (internal, do not use directly)
Documentation
use crate::derive_configuration_struct;
use crate::tests::pretty_print;

#[test]
fn simple_struct() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct SimpleConfig {
                enabled: bool,
                name: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn unit_struct() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct EmptyConfig;
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn public_struct() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            pub struct PublicConfig {
                pub enabled: bool,
                pub(crate) internal: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_defaults() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct ConfigWithDefaults {
                #[config(default)]
                enabled: bool,
                #[config(default = "default_name".to_string())]
                name: String,
                #[config(default = 42)]
                count: u32,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_required() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            /// If there are any required fields, we should not generate a Default impl
            struct ConfigWithRequired {
                #[config(required)]
                api_key: String,
                #[config(default = false)]
                debug: bool,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_all_required() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct AllRequiredConfig {
                #[config(required)]
                host: String,
                #[config(required)]
                port: u16,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_validation() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct ConfigWithValidation {
                #[config(pattern(r"^[a-z]+$"))]
                slug: String,
                #[config(range(min = 1, max = 100))]
                percentage: u8,
                #[config(length(min = 1, max = 256))]
                description: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_doc_comments() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            /// Configuration for the server.
            struct ServerConfig {
                /// The host to bind to.
                host: String,
                /// The port number.
                #[config(default = 8080)]
                port: u16,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_generics() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct GenericConfig<T> {
                value: T,
                name: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_preserves_existing_attributes() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            #[derive(PartialEq)]
            #[allow(dead_code)]
            struct AttributedConfig {
                #[serde(rename = "userName")]
                user_name: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}

#[test]
fn struct_with_cfg_attributes() {
    let output = derive_configuration_struct(
        Default::default(),
        syn::parse_quote! {
            struct FeatureGatedConfig {
                always_present: String,
                #[cfg(feature = "optional")]
                optional_field: String,
                #[cfg(all(feature = "a", feature = "b"))]
                multi_feature: String,
            }
        },
    )
    .unwrap();

    insta::assert_snapshot!(pretty_print(output));
}