unsplash / intlc

Compile ICU messages into code. Supports TypeScript and JSX. No runtime.
MIT License
56 stars 3 forks source link

Custom JSON parsing #115

Closed samhh closed 2 years ago

samhh commented 2 years ago

Depends #114.

Whilst implementing our own JSON parser seems a bit wild, we don't really need a full JSON parser on account of our input following a fairly rigid schema. This is mirrored in the relative simplicity of the added parser. And it gives us a great deal of flexibility, enabling as of this PR:

As with #114, both of the key error types are recoverable, and this recovery interoperates with other recoverable errors such as in message parsing. Note that failing to parse JSON is generally not recoverable.

Thus, given via intlc compile -l foo ./x-all.json:

{
  "dupeKey": {
    "message": ""
  },
  "badMsg": {
    "message": "{x, bad}"
  },
  "dupeKey": {
    "message": ""
  },
  "ok": {
    "message": ""
  },
  "badInnerKey": {
    "message": "",
    "beckand": ""
  }
}

Before:

badMsg:1:5:
  |
1 | {x, bad}
  |     ^^^^
unexpected "bad}"
expecting "boolean", "date", "number", "plural", "select", "selectordinal", "time", or white space

After:

./x-all.json:6:21:
  |
6 |     "message": "{x, bad}"
  |                     ^^^^^^
unexpected "bad}"<newline>  },<newline>  "
expecting "boolean", "date", "number", "plural", "select", "selectordinal", "time", or white space

./x-all.json:8:3:
  |
8 |   "dupeKey": {
  |   ^
Duplicate key: "dupeKey"

./x-all.json:16:5:
   |
16 |     "beckand": ""
   |     ^
unexpected '"'
expecting ""backend"", ""description"", '}', or white space

Detaching ourselves from Aeson decoding suggests we could and should implement our own encoder, which is really just going to be another "compiler" in the spirit of those we already have. This would solve our inability to pretty print flattened JSON output.

I'd additionally like to slightly modify the error output to include an additional line or two of context so that the offending key is visible (#116). Further refinements could also be made to various (sub)parsers to improve error output legibility.

samhh commented 2 years ago

For additional confidence given this is a big diff, I've run this against everything in Unsplash web and there are no errors. Inserted errors are caught.

samhh commented 2 years ago

Note to self: Add some end-to-end tests for multiple error reporting across different parser error types (keys, ICU, etc). Context: https://github.com/unsplash/intlc/pull/114#discussion_r865620631

samhh commented 2 years ago

@OliverJAsh Your suggestion for further tests caught two bugs with error reporting! One new and one preexisting. :sunglasses: