Closed FelixZY closed 3 months ago
The easiest way to do this yourself right now would be
splitPair().convert { (k, v) -> k.toWhatever() to v.toWhatever() }.multiple().toMap()
And we could definitely add the associate*
functions that are sugar for that.
Using clikt transforms to do the conversion sounds cool, but as you've seen it makes the API more complicated. I also think the error messages from that could be confusing, since they wouldn't mention the fact that they were part of a map.
Just came to request this. Glad to see it'll be in the next release!
Background
I've found myself in a situation where I want the user to provide a
Map<Long, MyEnum>
via the cli, something likeHowever, there seems to be no native support for other
associate
types thanMap<String, String>
in Clikt.What I looked for
Initially, I was thinking it might be possible to leverage a function similar to the standard library's
associateBy
. However, Clikt only exposes theassociate
function which does not fit my needs.I then found the
transformAll
,transformValue
andtransformEach
properties, but they were allval
s and did not seem intended for me to change after callingassociate
.Finally, I looked at the Clikt source code. Based on this, I was able to come up with a solution similar to this:
Unfortunately, this means I cannot use the
associate
sugar anymore. Also, I'm forced to run my own validations and miss out on nice error messages etc. provided by Clikt natively.Proposal
I propose introducing a custom
associateBy
function similar to this:There is a slight deviation from the standard library's
associateBy
in that we still callsplitPair
under the hood and do not ask the user to split the string themselves. However, I think this is acceptable sugar that additionally allows us to keep our key and value transforms short and to the point.What I really like about this solution is that we can rely on the ready-made
option
transforms insidekeyTransform
/valueTransform
, making it trivial to construct non-Map<String, String>
maps.An alternative is to continue with
associate
and add e.g.keyOptions
andvalueOptions
like this:However, I think this might be problematic as the user can now chain
.keyOptions().keyOptions().keyOptions().keyOptions()
or accidentally lose values after theassociate
step, e.g. if they define a constant return value forkeyOptions
. I also think this might be harder to implement.Finally, I think
associateBy
is better because key deduplication is more of an "expected" side effect ofassociate
/associateBy
thankeyOptions
IMO.