Having developed my own library to do this for internal projects I'd like to +1 
this proposal for the simple cases, although thanks to this discussion I've now 
learnt about enviable and I'll be using that for any future complex cases!

Cheers
Jon

On Tue, 18 Feb 2025, at 8:33 PM, dave.lu...@gmail.com wrote:
> 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
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/ea6e6238-edac-4dff-83bf-3ca60e30d1d1n%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-core+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/elixir-lang-core/7a7ee913-dcd7-415a-ad8c-4ca82d74c771%40app.fastmail.com.

Reply via email to