j-n-f / anodyne

An opinionated set of tools for building applications (mostly with `axum`)
MIT License
0 stars 0 forks source link

configuration: support setting app key #8

Open j-n-f opened 4 weeks ago

j-n-f commented 4 weeks ago

app key is currently hardcoded.

j-n-f commented 3 weeks ago

I've settled on https://github.com/rust-cli/config-rs

j-n-f commented 3 weeks ago

config-rs turned out to be insufficient for my needs.

I tried figment, but it also has some UX issues where the errors aren't as helpful as I'd hoped (e.g. errors need to be picked away one by one because serde finishes parsing on the first error): https://github.com/SergioBenitez/Figment/issues/131

Options:

  1. least time - continue using figment (it has much better error reporting than config-rs) and just deal with the problem later
    • There is one issue I can't see a way to resolve: if I don't specify any keys in a nested struct, it tells me that the name of the field in the parent struct is undefined. I'm not sure how to convert that into a helpful error message (e.g. you need to set this/these specific value(s) in the nested struct).
  2. compromise - write my own deserializer (which accumulates errors instead of exiting early) and build on top of derived Deserialize trait to save a bit of work
  3. most time - create my own derive macro which can:
    1. provide a full map of all envs required from the root struct (with descriptions and other metadata)
    2. deserialize from env values and report multiple errors

Another contender: https://github.com/greyblake/envconfig-rs

Supports nesting. I like the simplicity. Remains to be seen how it handles multiple errors.

I could imagine a simple PR to support listing all configs possible by making a few small changes to the derive macro.

Maybe I can just build my own version of something like envconfig-rs and be done with it. I like the approach (where anything that implements FromStr will just work, without having to fuss with the complexity of serde).

j-n-f commented 3 weeks ago

After a lot of headaches trying to get the perfect solution, it looks like the best approach is:

  1. Use Figment
  2. Specify reasonable defaults (so that forgotten values won't cause as many irritating run-error-update loops)
  3. Run some kind of validation on the deserialized config at startup time and exit early if there are any showstoppers.