Thanks Austin, this is quite comprehensive, but way beyond the scope of what I am proposing, which is to handle the two most common cases. For anything sufficiently complex, this should be the responsibility of the application/library.
On Tuesday, February 18, 2025 at 3:18:00 PM UTC-5 halos...@gmail.com wrote: > I also posted about it on Elixir Forum: > https://elixirforum.com/t/enviable-robust-environment-variable-conversion/69360 > > On Tue, Feb 18, 2025 at 3:16 PM Austin Ziegler <halos...@gmail.com> wrote: > >> I recently moved to a new position where we use Dotenvy and >> `System.get_env!` etc. I developed >> https://hexdocs.pm/enviable/Enviable.html on my own time and have >> released it. It's fairly comprehensive—and by fairly I mean extremely—and >> if there's something missing, I'm open to both requests and pull requests. >> >> It supports: >> >> - boolean >> - integer >> - float >> - atom (and safe atom) also with constraints >> - module (and safe module) also with constraints >> - Elixir and Erlang code evaluation >> - PEM decoding >> - baseX decoding (and subsequent casting if required) >> - list splitting (and subsequent casting) >> >> I'm sure I’m missing something. >> >> We aren't using it at work yet, but the team is looking forward to when >> we have a bit of breathing room to make this happen. >> >> -a >> >> On Tue, Feb 18, 2025 at 11:31 AM Zach Daniel <zachary....@gmail.com> >> wrote: >> >>> Hm…that makes sense. I’d maintain that it should end in a `!` for >>> clarity though, even if there is no non-raising variant. >>> >>> On Feb 18, 2025, at 11:28 AM, dave.lu...@gmail.com <dave.lu...@gmail.com> >>> wrote: >>> >>> > I think a simpler alternative to an `as` option might be: >>> >>> > `System.get_boolean_env/1` and `System.get_integer_env/1` that return >>> things like: >>> >>> > `{:invalid, value}` when the value can’t be parsed, but provide ! >>> versions that raise errors, i.e >>> >>> I do aree with type specific functions, but I don't agree with adding >>> non-raising variants as this is intended to be an ergonomic improvement to >>> existing usage patterns. If the value is not parseable, it should raise. If >>> you have a more complex usage pattern, use the existing `System.get_env/2` >>> and do your own parsing >>> >>> On Tuesday, February 18, 2025 at 11:18:48 AM UTC-5 zachary....@gmail.com >>> wrote: >>> >>>> I think a simpler alternative to an `as` option might be: >>>> >>>> `System.get_boolean_env/1` and `System.get_integer_env/1` that return >>>> things like: >>>> >>>> `{:invalid, value}` when the value can’t be parsed, but provide ! >>>> versions that raise errors, i.e >>>> >>>> ```elixir >>>> config :something, port: System.get_integer_env!(“SERVER_PORT”) >>>> ``` >>>> >>>> Raising something like >>>> >>>> ```elixir >>>> Expected SERVER_PORT to be an integer, got <something> >>>> ``` >>>> >>>> On Feb 18, 2025, at 11:15 AM, Cocoa Xu <i...@uwucocoa.moe> wrote: >>>> >>>> This would be quite helpful to deal with environment variables that are >>>> expected to be boolean or integers. In my experience, I always have to >>>> copy-paste a helper function to do the type cast: >>>> >>>> defp to_boolean(nil), do: false >>>> >>>> defp to_boolean(var) when is_boolean(var) do >>>> var >>>> end >>>> >>>> defp to_boolean(var) do >>>> String.downcase(to_string(var)) in ["1", "true", "on", "yes", "y"] >>>> end >>>> >>>> >>>> On Tuesday, February 18, 2025 at 5:07:50 PM UTC+1 dave.lu...@gmail.com >>>> wrote: >>>> >>>>> In Elixir applications, config/runtime.exs is often used to parse >>>>> environment variables from System.get_env2/ and friends, and convert into >>>>> Application configuration. >>>>> >>>>> Since environment variables can only be strings, it is often necessary >>>>> to cast from string values into booleans and integer values. E.g. >>>>> >>>>> config :my_app, :bool_value, System.get_env("BOOL_VALUE") == "true" >>>>> >>>>> config :my_app, :int_value, >>>>> String.to_string(System.get_env("INT_VALUE", "5")) >>>>> >>>>> While there are entire libraries that deal with advanced runtime >>>>> configuration, like Vapor <https://github.com/elixir-toniq/vapor> and >>>>> elixir-specify <https://github.com/Qqwy/elixir-specify>, I believe >>>>> there is an opportunity to simplify common patterns and duplicative code >>>>> in >>>>> Elixir configuration that often leads to confusion and edge case issues. >>>>> >>>>> My proposal is to add parsing for both booleans and integers to >>>>> environment variable parsing. As an example: >>>>> >>>>> config :my_app, :bool_value, System.get_env_as!("BOOL_VALUE", "false", >>>>> as: :boolean) >>>>> >>>>> config :my_app, :int_value, System.get_env_as!("INT_VALUE", "5", as: >>>>> :integer) >>>>> >>>>> The trickiness would be in the acceptable range of edge case values. >>>>> For example, "1" and "0" are often used for boolean values, in addition >>>>> to >>>>> "TRUE" and "FALSE". I believe there could be a reasonable compromise and >>>>> appropriate documentation for addressing these issues. >>>>> >>>>> More complex parsing, such as floats and custom data types would not >>>>> be supported. >>>> >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "elixir-lang-core" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to elixir-lang-co...@googlegroups.com. >>>> To view this discussion visit >>>> https://groups.google.com/d/msgid/elixir-lang-core/562c5949-fde0-4f3d-9357-d57aa1f9d4b3n%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/elixir-lang-core/562c5949-fde0-4f3d-9357-d57aa1f9d4b3n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>>> >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to elixir-lang-co...@googlegroups.com. >>> To view this discussion visit >>> https://groups.google.com/d/msgid/elixir-lang-core/f3bdb53b-d44b-4559-8cc6-9cdcb203c513n%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/elixir-lang-core/f3bdb53b-d44b-4559-8cc6-9cdcb203c513n%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to elixir-lang-co...@googlegroups.com. >>> To view this discussion visit >>> https://groups.google.com/d/msgid/elixir-lang-core/A281A8D1-A3EB-43B7-AB76-9B8863DD32D6%40gmail.com >>> >>> <https://groups.google.com/d/msgid/elixir-lang-core/A281A8D1-A3EB-43B7-AB76-9B8863DD32D6%40gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> >> >> -- >> Austin Ziegler • halos...@gmail.com • aus...@halostatue.ca >> http://www.halostatue.ca/ • http://twitter.com/halostatue >> > > > -- > Austin Ziegler • halos...@gmail.com • aus...@halostatue.ca > http://www.halostatue.ca/ • http://twitter.com/halostatue > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/ea6e6238-edac-4dff-83bf-3ca60e30d1d1n%40googlegroups.com.