-
-
Notifications
You must be signed in to change notification settings - Fork 120
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
Preserving Map and Set types, and handling Complex Keys #78
Comments
Supporting idempotence on JS/YAML transformations does seem like a pretty good goal. So far I've mainly focused on making sure that YAML -> Document -> YAML transformations stay as constant as possible. Fundamentally, the most difficult part to handle here is that the default Core Schema of YAML 1.2 only supports the import YAML from 'yaml'
import omap from 'yaml/types/omap'
import set from 'yaml/types/set'
YAML.defaultOptions.tags = [omap, set]
YAML.stringify(new Map([[42, 'x']])) // '!!omap\n- 42: x\n'
YAML.parse(YAML.stringify(new Map([[42, 'x']]))) // Map { 42 => 'x' }
YAML.stringify(new Set([true, false])) // '!!set\n? true\n? false\n'
YAML.parse(YAML.stringify(new Set([true, false]))) // Set { true, false } Besides the above, there's the question of how to represent in JavaScript maps with non-string keys and maps with all-null values when using the default schema, and for that case I think you're right, the I do not think that considering the string representation style of the YAML key is by itself sufficient, as e.g. Does that about cover the cases that you had in mind, or did I miss some part? |
I think that does cover it fairly well, and explicitly using I'm not getting a Set out of |
Nope, that's a bug. This is wrong: const good = YAML.stringify(new Set([1, 2])) // '!!set\n? 1\n? 2\n'
const bad = YAML.stringify({ set: new Set([1, 2]) }) // 'set:\n ? 1\n ? 2\n' The |
Thanks for fixing. I think with that in place, I have clear way to ensure that Maps turn into Maps and Sets turn into Sets, in both directions. I'll close this issue, I agree that the implicit handling is probably too spooky. |
Maps with complex keys are stringified properly, as one would expect, with
? key: ...\n: value
. However, when parsed, the key is converted to a JSON string.output:
I realize that I can use the
mapAsMap
option to always use Map objects instead of plain old javascript objects, but this isn't ideal, since it converts plain JavaScript objects to Map objects. As a result, either we always convert Map objects to POJOs, or always convert POJOs to Maps. I'd like a way to deterministically return a Map for a Map, and a POJO for a POJO.Map Handling Proposal:
new Map([['x', 'y']])
would stringify topreserveMapType
option to use this behavior.Similarly with Set objects, a set like
new Set([1, 2, 3, 3])
will end up being converted to the JavaScript array[1, 2, 3]
. However, a Set is more closely aligned with the yaml Set type:or in flow lingo:
{1, 2, 3}
.So, a similar proposal for handling Set objects could be:
?
key and no value, return a Set object rather than an array.preserveSetType
option to use this behavior.The rule of thumb I'd like to get to is that, for as many objects as possible:
yaml.stringify(object) === yaml.stringify(yaml.parse(yaml.stringify(object)))
.I'm happy to dig into the code to prepare a PR if this seems like an acceptable design. Thanks for your consideration.
The text was updated successfully, but these errors were encountered: