So it turns out cprop cannot handle niling a setting. After some looking around and some testing I think the problem is just one of unnecessary complexity:
The str->value function tries to be smart and does some long/boolean/string regex matching before sending the value to edn/read-string. This processing is both unnecessary and can actually limit functionality as mentioned in the title:
cprop.source> (let [or-nil #(or % "nil")]
(doseq [v ["hello" -1 100 100000000000000000000 -100000000000000000000 nil true false]
:let [cprop (str->value (str v) {})
edn (edn/read-string (str v))]]
(clojure.pprint/print-table [:parser :value :type]
[{:parser "" :value (or-nil (str v)) :type (or-nil (type v))}
{:parser "cprop" :value (or-nil cprop) :type (or-nil (type cprop))}
{:parser "edn" :value (or-nil edn) :type (or-nil (type edn))}])))
| :parser | :value | :type |
|---------+--------+---------------------------|
| | hello | class java.lang.String |
| cprop | hello | class java.lang.String |
| edn | hello | class clojure.lang.Symbol |
| :parser | :value | :type |
|---------+--------+----------------------|
| | -1 | class java.lang.Long |
| cprop | -1 | class java.lang.Long |
| edn | -1 | class java.lang.Long |
| :parser | :value | :type |
|---------+--------+----------------------|
| | 100 | class java.lang.Long |
| cprop | 100 | class java.lang.Long |
| edn | 100 | class java.lang.Long |
| :parser | :value | :type |
|---------+-----------------------+---------------------------|
| | 100000000000000000000 | class clojure.lang.BigInt |
| cprop | 100000000000000000000 | class clojure.lang.BigInt |
| edn | 100000000000000000000 | class clojure.lang.BigInt |
| :parser | :value | :type |
|---------+------------------------+---------------------------|
| | -100000000000000000000 | class clojure.lang.BigInt |
| cprop | -100000000000000000000 | class clojure.lang.BigInt |
| edn | -100000000000000000000 | class clojure.lang.BigInt |
| :parser | :value | :type |
|---------+--------+------------------------|
| | nil | nil |
| cprop | | class java.lang.String |
| edn | nil | nil |
| :parser | :value | :type |
|---------+--------+-------------------------|
| | true | class java.lang.Boolean |
| cprop | true | class java.lang.Boolean |
| edn | true | class java.lang.Boolean |
| :parser | :value | :type |
|---------+--------+-------------------------|
| | false | class java.lang.Boolean |
| cprop | nil | class java.lang.Boolean |
| edn | nil | class java.lang.Boolean |
nil
I'm fairly certain simply removing the regex matching from str->value would only add functionality to the parsing. Anecdotally: before babashka supported cprop as a library, I mimic'd the behavior using just edn/read-string and it worked like a charm.
So it turns out
cpropcannot handleniling a setting. After some looking around and some testing I think the problem is just one of unnecessary complexity:The
str->valuefunction tries to be smart and does some long/boolean/string regex matching before sending the value toedn/read-string. This processing is both unnecessary and can actually limit functionality as mentioned in the title:I'm fairly certain simply removing the regex matching from
str->valuewould only add functionality to the parsing. Anecdotally: before babashka supportedcpropas a library, I mimic'd the behavior using justedn/read-stringand it worked like a charm.