mirror of
https://github.com/corn-config/corn.git
synced 2026-07-11 05:16:10 +01:00
[GH-ISSUE #49] libcorn passes all environment variables to serde as strings, regardless of the underlying type #17
Labels
No labels
bug
bug
documentation
enhancement
enhancement
pull-request
tooling
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
corn-config/corn#17
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @tarka on GitHub (Dec 22, 2025).
Original GitHub issue: https://github.com/corn-config/corn/issues/49
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):
And this config file:
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\")'"(orDeserializationError("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-withor similar). However the user could potentially supply any variable, so everything would end up being a string.@tarka commented on GitHub (Dec 22, 2025):
There's a full test-case here if it helps: https://github.com/tarka/corn-test/blob/main/src/lib.rs
@JakeStanger commented on GitHub (Dec 22, 2025):
Interesting, this is definitely an oversight.
In my head env vars would always be strings because that's how the OS treats them, but the specification doesn't actually state that (and even gives an integer-based example) and this is definitely a valid usecase.
Currently you will have to treat all env vars as strings and work around that the best you can, either with serde or by parsing in code. I am definitely open to amending that though.
@tarka commented on GitHub (Dec 23, 2025):
One quick workaround for this would be to specify that non-string $env inputs should have a default. This would allow you to use the inputs lookup to retrieve the expected type and attempt a coercion. This would only really work with primitive types though (int, float, bool). But that would probably cover most normal cases. I've hacked together a quick proof-of-concept here and it works for the example above.
Obviously it would be much better to retrieve the type from the underlying deserialisation target.