Skip to content

libcorn passes all environment variables to serde as strings, regardless of the underlying type #49

@tarka

Description

@tarka

Having native environment variable injection is a powerful feature as it allows 12-factor type configuration, however it doesn't play well with non-string types (AFAICS; happy to be proven wrong).

e.g. If you have the following config definitions (based on a real use-case):

#[derive(Deserialize)]
pub struct Insecure {
    pub port: u16,
    pub redirect: bool,
}

#[derive(Deserialize)]
pub struct TlsConfig {
    pub port: u16,
}

#[derive(Deserialize)]
pub struct Config {
    pub insecure: Insecure,
    pub tls: TlsConfig,
}

And this config file:

let {
    $env_INSECURE_PORT = 80
    $env_INSECURE_REDIRECT = true
    $env_TLS_PORT = 443
} in {
    insecure = {
        port = $env_INSECURE_PORT
        redirect = $env_INSECURE_REDIRECT
    }
    tls = {
        port = $env_TLS_PORT
    }
}

If you deserialise with no environment variables set then it works fine. However setting any of the env-vars will result in DeserializationError("Expected integer (u16), found 'String(\"8080\")'" (or DeserializationError("Expected boolean, found 'String(\"false\")'")).

I'm not sure if there's any simple workaround for this? It looks like the only way is to make any variables that may be provided from the environment into strings an have serde parse them into the appropriate type (with serde-with or similar). However the user could potentially supply any variable, so everything would end up being a string.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions