Prismatic/schema — pull request #116 by glenjamin (2014-06-22 23:39:07+00:00)
Title: Coercion of explicit keys in maps

Hi, this isn't finished and I'm not sure this is quite the right approach, but I wanted to share my WIP for some feedback.

My initial issue was wanting to specify a schema with keyword keys, but have the coercion accept string keys.

Here's what I've done / found / thought:

* Added some testcases for map key coercion
* The generic extra-keys testcase already worked
* The specific-keys cases do not allow for key coercion
* Refactored `MapEntry/walker` to treat explicit keys as an `eq` schema, this ensures that the walkers are called recursively on all keys, and removes quite a bit of code duplication - even without the other changes this seems like a good move to me (ignoring the keyword?/delay hacks)
* The `delay` there is a bit of a hack to have a local binding in the right scope that doesn't error when `(specific-key? kspec)` is `false`. I'm not massively keen on this. If the `keyword?` special-case is removed then `k` only appears twice and simply repeating `(explicit-schema-key kspec)` is more palatable.
* The code so far makes the coercion work for the MapEntry schema, but still thinks the key is missing because the `(find x wk)` in `map-walker` operates on the un-coerced map

I'm not quite sure where to go from here, assuming key-coercion like this is desirable.

One option would be to walk the `MapEntry`s before checking for required keys, and doing that in a second pass afterwards.

Another option would be to leave the coercion out of MapEntry entirely, and do it at the Map level, although this seems like it would be an n*m operation to try all the various combinations.

Anyway, sorry for this being a bit of a braindump - I got a bit down the rabbit-hole after the initial surprise of string->keyword keys not just working!