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

Maps with complex keys aren't supported #182

Closed
robbiemcmichael opened this issue Nov 2, 2019 · 1 comment · Fixed by #183
Closed

Maps with complex keys aren't supported #182

robbiemcmichael opened this issue Nov 2, 2019 · 1 comment · Fixed by #183

Comments

@robbiemcmichael
Copy link
Contributor

robbiemcmichael commented Nov 2, 2019

The YAML spec supports map keys which are any YAML value. The yaml library currently doesn't support support this.

Here's an example with the rarely used syntax to prove that it does work with libyaml:

$ cat map.yaml 
? foo: 1
  bar: 2
: true
> (runResourceT . runConduit $ Text.Libyaml.decodeFile "map.yaml" .| consume) >>= pPrint
[ EventStreamStart
, EventDocumentStart
, EventMappingStart NoTag BlockMapping Nothing
, EventMappingStart NoTag BlockMapping Nothing
, EventScalar "foo" NoTag Plain Nothing
, EventScalar "1" NoTag Plain Nothing
, EventScalar "bar" NoTag Plain Nothing
, EventScalar "2" NoTag Plain Nothing
, EventMappingEnd
, EventScalar "true" NoTag Plain Nothing
, EventMappingEnd
, EventDocumentEnd
, EventStreamEnd
] 

It's not possible to support this when decoding YAML as an Aeson Value because an Object is a HashMap Text Value (which matches the JSON spec).

There are a few places in the yaml library where we could make the change:

It would however be a breaking change for both and result in the situation where we can construct values which can't be converted to an Aeson Value. It doesn't look like it would break the normal decoders as these go straight from an Event to a Value and already throw an exception:

> Data.Yaml.decodeFileEither "map.yaml" :: IO (Either ParseException Value)
Left (UnexpectedEvent {_received = Just (EventMappingStart NoTag BlockMapping Nothing), _expected = Nothing})

I think the sensible options here are one of the following:

  1. Support maps with complex keys where we can to stay true to the YAML spec.
  2. Document the intention to restrict users to the subset of the YAML which allows for conversion to JSON values. Add a ParseException value to represent the error and prevent an exception being thrown when attempting to parse unsupported YAML values.
@snoyberg
Copy link
Owner

snoyberg commented Nov 3, 2019

I think we can address Data.Yaml.Builder by providing a mappingComplex or similar function as an alternative to mapping. And I'd be in favor of tending towards doc fixes here. Is there a real life example of people wanting complex keys for YAML?

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

Successfully merging a pull request may close this issue.

2 participants