Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment Variable List of Structs #603

Open
0xForerunner opened this issue Nov 4, 2024 · 6 comments
Open

Environment Variable List of Structs #603

0xForerunner opened this issue Nov 4, 2024 · 6 comments

Comments

@0xForerunner
Copy link

Tracking issue for #597

Support parsing environment variables into a list of structs.

Example

    #[derive(Deserialize, Debug, PartialEq)]
    struct Struct {
        a: Vec<Option<u32>>,
        b: u32,
    }

    #[derive(Deserialize, Debug)]
    struct ListOfStructs {
        list: Vec<Struct>,
    }

    let values = vec![
        ("LIST_0_A_0".to_owned(), "1".to_owned()),
        ("LIST_0_A_2".to_owned(), "2".to_owned()),
        ("LIST_0_B".to_owned(), "3".to_owned()),
        ("LIST_1_A_1".to_owned(), "4".to_owned()),
        ("LIST_1_B".to_owned(), "5".to_owned()),
    ];

    let environment = Environment::default()
        .separator("_")
        .try_parsing(true)
        .source(Some(values.into_iter().collect()));

    let config = Config::builder().add_source(environment).build().unwrap();

    let config: ListOfStructs = config.try_deserialize().unwrap();
    assert_eq!(
        config.list,
        vec![
            Struct {
                a: vec![Some(1), None, Some(2)],
                b: 3
            },
            Struct {
                a: vec![None, Some(4)],
                b: 5
            },
        ]
    );
@epage
Copy link
Contributor

epage commented Nov 21, 2024

Could you find prior art for array env variables like this? It can help for identifying any lessons learned that are worth applying.

I know Cargo has played with supporting more structured env variables (rust-lang/cargo#7406) but there are complexities there and no one has really been pushing that forward.

@0xForerunner
Copy link
Author

This project seems to use a similar approach as I've taken here. I can't really imagine another way of doing it at the moment.

@epage
Copy link
Contributor

epage commented Nov 21, 2024

git puts the index in a weird spot but they also require a _COUNT variable

From https://git-scm.com/docs/git-config#ENVIRONMENT

GIT_CONFIG_COUNT
GIT_CONFIG_KEY_<n>
GIT_CONFIG_VALUE_<n>

If GIT_CONFIG_COUNT is set to a positive number, all environment pairs GIT_CONFIG_KEY_<n> and GIT_CONFIG_VALUE_<n> up to that number will be added to the process’s runtime configuration. The config pairs are zero-indexed. Any missing key or value is treated as an error. An empty GIT_CONFIG_COUNT is treated the same as GIT_CONFIG_COUNT=0, namely no pairs are processed. These environment variables will override values in configuration files, but will be overridden by any explicit options passed via git -c.

This is useful for cases where you want to spawn multiple git commands with a common configuration but cannot depend on a configuration file, for example when writing scripts.

@0xForerunner
Copy link
Author

I'm not sure I grasp why _COUNT should be here, as it can always be inferred.

@0xForerunner
Copy link
Author

@epage any other thoughts or suggestions on this implementation? #597

@epage
Copy link
Contributor

epage commented Dec 9, 2024

I'm a bit uncomfortable ignoring git's precedence without knowing more of why they chose what they did and if it applies.

I would also prefer more input and/or prior art as we would be deciding a policy for applications that would be hard to change in the future. While we can easily just bump our major version, CLIs that use this might not have such an easy time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants