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.

Reply via email to