Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-parse booleans (true / false), nil, and numbers? #10

Closed
borkdude opened this issue Jun 7, 2022 · 4 comments
Closed

Auto-parse booleans (true / false), nil, and numbers? #10

borkdude opened this issue Jun 7, 2022 · 4 comments

Comments

@borkdude
Copy link
Contributor

borkdude commented Jun 7, 2022

It could be reasonable behaviour to auto-parse "false" as false and "nil" as nil. This would in some cases reduce the amount of :coerce config to zero.

Furthermore it could also be reasonable behavior to auto-parse 123 as a number.
Anything else is still parsed as a string.

We should be able to disable the auto-parsing.

{:no-auto-parse true}

and/or in the future:

{:no-auto-parse #{:number :number}}

Could there be a case where you want to have a new 1foo? This seems very unlikely. We could also revert to the string in case of edn/read-string failure.

Would you have want to have false, true? This seems unlikely and if so, you could coerce them to strings, if that is desired.

@millettjon
Copy link

Here are some examples of conventions used in other libraries.

yogthos/config takes the following approach for coercing environment variables:

The values are parsed using the following strategy:

  1. [0-9]+ -> number
  2. ^(true|false)$ -> boolean
  3. \w+ -> string
  4. try parse as EDN, and return the original value as the default

tolitius/cprop does something similar for environment variables and system properties:

str->value will convert:
* numbers to longs
* alphanumeric values to strings
* true/false to boolean
* and will use Clojure reader for the rest
in case reader can't read OR it reads a symbol, the value will be returned as is (a string)

@borkdude
Copy link
Contributor Author

borkdude commented Jun 26, 2022

Thanks. I've looked into @yogthos's str->value function:

(defn str->value
  "ENV vars and system properties are strings. str->value will convert:
   the numbers to longs, the alphanumeric values to strings, and will use Clojure reader for the rest
   in case reader can't read OR it reads a symbol, the value will be returned as is (a string)"
  [v]
  (cond
    (re-matches #"[0-9]+" v) (parse-number v)
    (re-matches #"^(true|false)$" v) (Boolean/parseBoolean v)
    (re-matches #"\w+" v) v
    :else
    (try
      (let [parsed (edn/read-string v)]
        (if (symbol? parsed) v parsed))
      (catch Throwable _ v))))

I think this could just be simplified as: always a read as in, but when the result is a symbol, return the original string and in case of an error too?

@borkdude
Copy link
Contributor Author

Although:

user=> (conf/str->value "1M")
"1M"

I think in this case one would like to have 1M instead of "1M".

borkdude added a commit that referenced this issue Jun 26, 2022
borkdude added a commit that referenced this issue Jun 26, 2022
borkdude added a commit that referenced this issue Jun 26, 2022
@borkdude
Copy link
Contributor Author

I've put in place some automatic coercions now. Documented here:

https://github.com/babashka/cli/blob/main/API.md#auto-coerce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants