Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ What changed for someone using zig-hocon: the Zig package, the `hocon` command l

## [Unreleased]

### Changed

- A value that begins with a digit but is no number is text again, as the spec has it: `host = 127.0.0.1`, `1.2.3`, a UUID and `01` are the strings they were written as, no longer a `BadNumber` error, so an IP address needs no quotes. The number JSON reads at the start is followed by text, as `10.0bar` is; the spec's own `1.2.3`, a path in a key, is written the same way in a value. So is a value that begins with `-` and no number: `-foo`, `-Xmx2g`, `--verbose`, and the `-` in `Monty Python - Holy Grail`, no longer a `HyphenIsNotAJsonNumber` error. So are `-.5` and `-.33e1`, which JSON has no number for, as `.5` already was. A `+` outside a number, `1+2` or `-.33e+1`, stays an error. Seven new conformance cases, eight rows rewritten, all 476 pass.

### Added

- Twelve conformance cases from bug reports in lightbend/config and ekrich/sconfig where the spec has the answer: typesafe/config fails inside `${a} { … }`, turns integers past 2^63 into strings and accepts `\u+041`; pyhocon loses `+=` across an include and the text of a substituted number. zig-hocon passes all 469.
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The rest of this page reads these two files.

## Why zig-hocon

- **Correct.** Passes all 469 tests in the [conformance suite](https://htmlpreview.github.io/?https://github.com/lejmr/zig-hocon/blob/main/conformance/report.html), one test for each sentence of the spec.
- **Correct.** Passes all 476 tests in the [conformance suite](https://htmlpreview.github.io/?https://github.com/lejmr/zig-hocon/blob/main/conformance/report.html), one test for each sentence of the spec.
- **Your schema is a Zig struct.** HOCON is only what sits on disk; the struct says what it holds, with defaults, optionals, enums, durations and sizes.
- **Fast.** A 10 MB config in a quarter of a second.\*
- **Clear errors.** File, line, column and a caret, also for a value of the wrong type.
Expand Down Expand Up @@ -210,13 +210,13 @@ b.step("check-config", "Check the config against Config").dependOn(&check.step);

| implementation | against the spec | against typesafe/config 1.4.9 |
|---|---|---|
| Java <sub>typesafe/config 1.4.9</sub> | 87.4% (410/469) | 100% (469/469) |
| hocon2 <sub>hocon2 0.6.3</sub> | 82.5% (387/469) | 76.8% (360/469) |
| pulse-pyhocon <sub>pulse-pyhocon 0.2.1</sub> | 67.6% (317/469) | 65.2% (306/469) |
| py.hocon <sub>hocon-parser 1.14.2 (Python)</sub> | 84.9% (398/469) | 84.2% (395/469) |
| pyhocon <sub>pyhocon 0.3.63</sub> | 69.1% (324/469) | 64.2% (301/469) |
| rs.hocon <sub>hocon-parser 1.14.2 (Rust)</sub> | 84.9% (398/469) | 82.3% (386/469) |
| zig-hocon <sub>zig-hocon code@d844ec9</sub> | 100% (469/469) | 87.4% (410/469) |
| Java <sub>typesafe/config 1.4.9</sub> | 88.0% (419/476) | 100% (476/476) |
| hocon2 <sub>hocon2 0.6.3</sub> | 81.1% (386/476) | 75.2% (358/476) |
| pulse-pyhocon <sub>pulse-pyhocon 0.2.1</sub> | 66.6% (317/476) | 62.8% (299/476) |
| py.hocon <sub>hocon-parser 1.14.2 (Python)</sub> | 83.6% (398/476) | 81.3% (387/476) |
| pyhocon <sub>pyhocon 0.3.63</sub> | 70.4% (335/476) | 64.7% (308/476) |
| rs.hocon <sub>hocon-parser 1.14.2 (Rust)</sub> | 83.6% (398/476) | 80.7% (384/476) |
| zig-hocon <sub>zig-hocon code@a40d962</sub> | 100% (476/476) | 88.0% (419/476) |

The table keeps the best parsers; the others measured, and why they are not in it: [conformance/README.md](conformance/README.md#not-in-the-table).

Expand Down
12 changes: 6 additions & 6 deletions conformance/maintaining/COVERAGE.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ <h3>Unchanged from JSON</h3>
<p data-line="117"> - <mark class="ok" title="unchanged-from-json.1 — unchanged-from-json/024-raw-utf8-in-quoted-string.conf">files must be valid UTF-8</mark>
- <mark class="ok" title="unchanged-from-json.2 — unchanged-from-json/001-quoted-string-json-format.conf, unchanged-from-json/015-remaining-json-escapes.conf, unchanged-from-json/016-unknown-escape-illegal.conf, unchanged-from-json/017-non-hex-unicode-escape-illegal.conf, unchanged-from-json/018-unterminated-quoted-string-illegal.conf, unchanged-from-json/019-backslash-at-end-of-file-illegal.conf, unchanged-from-json/020-unicode-escape-cut-off-by-end-of-file-illegal.conf, unchanged-from-json/026-surrogate-pair-escape.conf, unchanged-from-json/027-unpaired-surrogate-escape-is-kept.conf, unchanged-from-json/029-unicode-escape-with-a-sign-is-invalid.conf, unchanged-from-json/030-unicode-escape-with-non-ascii-digits-is-invalid.conf">quoted strings are in the same format as JSON strings</mark>
- <mark class="ok" title="unchanged-from-json.3 — unchanged-from-json/002-string-value-type.conf, unchanged-from-json/003-number-value-type.conf, unchanged-from-json/004-object-value-type.conf, unchanged-from-json/005-array-value-type.conf, unchanged-from-json/006-boolean-value-type.conf, unchanged-from-json/007-null-value-type.conf, unchanged-from-json/028-integer-beyond-64-bits-is-a-number.conf">values have possible types: string, number, object, array, boolean, null</mark>
- <mark class="ok" title="unchanged-from-json.4 — unchanged-from-json/008-number-format-decimal-and-exponent.conf, unchanged-from-json/009-number-leading-zero-illegal.conf, unchanged-from-json/010-negative-number-without-integer-part-illegal.conf, unchanged-from-json/011-negative-exponent-number-without-integer-part-illegal.conf, unchanged-from-json/012-number-with-trailing-dot-illegal.conf, unchanged-from-json/013-trailing-dot-before-exponent-illegal.conf, unchanged-from-json/014-negative-leading-zeros-illegal.conf, unchanged-from-json/023-64-bit-integer.conf, unchanged-from-json/025-nan-is-not-a-number.conf, unchanged-from-json/028-integer-beyond-64-bits-is-a-number.conf">allowed number formats matches JSON; as in JSON, some possible
- <mark class="ok" title="unchanged-from-json.4 — unchanged-from-json/008-number-format-decimal-and-exponent.conf, unchanged-from-json/009-leading-zero-run-is-text.conf, unchanged-from-json/010-signed-fraction-without-integer-part-is-text.conf, unchanged-from-json/011-plus-in-a-signed-fraction-is-illegal.conf, unchanged-from-json/012-trailing-dot-run-is-text.conf, unchanged-from-json/013-trailing-dot-before-exponent-is-text.conf, unchanged-from-json/014-negative-leading-zeros-are-text.conf, unchanged-from-json/023-64-bit-integer.conf, unchanged-from-json/025-nan-is-not-a-number.conf, unchanged-from-json/028-integer-beyond-64-bits-is-a-number.conf, unchanged-from-json/031-exponent-with-a-plus-sign.conf, unchanged-from-json/032-signed-fraction-with-exponent-is-text.conf">allowed number formats matches JSON; as in JSON, some possible
floating-point values are not represented, such as `NaN`</mark></p>
<h3>Comments</h3>
<p data-line="125"><mark class="ok" title="comments.1 — comments/001-hash-comment.conf, comments/002-double-slash-comment.conf, comments/003-whole-line-comment.conf, comments/004-comment-stops-at-newline.conf, comments/005-hash-inside-quoted-string-is-not-a-comment.conf, comments/006-double-slash-inside-quoted-string-is-not-a-comment.conf, comments/007-comment-between-separator-and-value.conf, comments/008-comment-then-blank-line-then-field.conf, comments/009-comment-inside-object.conf, comments/010-comments-inside-array.conf, comments/011-comment-before-values-of-every-type.conf, comments/013-line-comment-after-array.conf, comments/014-hash-comment-after-array-without-space.conf">Anything between `//` or `#` and the next newline is considered a comment
Expand Down Expand Up @@ -163,30 +163,30 @@ <h3>Duplicate keys and object merging</h3>
<h3>Unquoted strings</h3>
<p data-line="242"><mark class="ok" title="unquoted-strings.1 — unquoted-strings/001-simple-unquoted-string.conf">A sequence of characters outside of a quoted string is a string
value if:</mark></p>
<p data-line="245"> - <mark class="ok" title="unquoted-strings.2 — unquoted-strings/003-unquoted-cannot-contain-at-sign.conf, unquoted-strings/011-unquoted-cannot-contain-backslash.conf, unquoted-strings/015-reserved-forbidden-char-no-current-meaning.conf, unquoted-strings/019-dollar-must-start-a-substitution.conf, unquoted-strings/020-plus-must-be-followed-by-equals.conf">it does not contain &quot;forbidden characters&quot;: &#x27;$&#x27;, &#x27;&quot;&#x27;, &#x27;{&#x27;, &#x27;}&#x27;,
<p data-line="245"> - <mark class="ok" title="unquoted-strings.2 — unchanged-from-json/011-plus-in-a-signed-fraction-is-illegal.conf, unquoted-strings/003-unquoted-cannot-contain-at-sign.conf, unquoted-strings/011-unquoted-cannot-contain-backslash.conf, unquoted-strings/015-reserved-forbidden-char-no-current-meaning.conf, unquoted-strings/019-dollar-must-start-a-substitution.conf, unquoted-strings/020-plus-must-be-followed-by-equals.conf">it does not contain &quot;forbidden characters&quot;: &#x27;$&#x27;, &#x27;&quot;&#x27;, &#x27;{&#x27;, &#x27;}&#x27;,
&#x27;[&#x27;, &#x27;]&#x27;, &#x27;:&#x27;, &#x27;=&#x27;, &#x27;,&#x27;, &#x27;+&#x27;, &#x27;#&#x27;, &#x27;`&#x27;, &#x27;^&#x27;, &#x27;?&#x27;, &#x27;!&#x27;, &#x27;@&#x27;,
&#x27;*&#x27;, &#x27;&amp;&#x27;, &#x27;\&#x27; (backslash), or whitespace.</mark>
- <mark class="ok" title="unquoted-strings.3 — unquoted-strings/004-double-slash-starts-comment.conf, unquoted-strings/005-single-slash-allowed.conf">it does not contain the two-character string &quot;//&quot; (which
starts a comment)</mark>
- <mark class="ok" title="unquoted-strings.4 — unquoted-strings/007-footrue-is-one-unquoted-string.conf">its initial characters do not parse as `true`, `false`, `null`,
- <mark class="ok" title="unquoted-strings.4 — unchanged-from-json/009-leading-zero-run-is-text.conf, unchanged-from-json/010-signed-fraction-without-integer-part-is-text.conf, unchanged-from-json/012-trailing-dot-run-is-text.conf, unchanged-from-json/013-trailing-dot-before-exponent-is-text.conf, unchanged-from-json/014-negative-leading-zeros-are-text.conf, unchanged-from-json/032-signed-fraction-with-exponent-is-text.conf, unquoted-strings/007-footrue-is-one-unquoted-string.conf, unquoted-strings/012-hyphen-before-a-letter-is-text.conf, unquoted-strings/022-digit-then-exponent-letter-is-text.conf, unquoted-strings/025-digit-initial-non-number-is-text.conf, unquoted-strings/026-ip-address-is-text.conf, unquoted-strings/027-uuid-is-text.conf, unquoted-strings/028-lone-hyphen-is-text.conf, unquoted-strings/029-command-line-flags-are-text.conf, unquoted-strings/030-hyphen-between-words-is-text.conf">its initial characters do not parse as `true`, `false`, `null`,
or a number.</mark></p>
<p data-line="253"><mark class="ok" title="unquoted-strings.5 — unquoted-strings/024-escape-sequence-in-unquoted-string-illegal.conf">Unquoted strings are used literally, they do not support any kind
of escaping.</mark> <mark class="ok" title="unquoted-strings.6 — unquoted-strings/002-quoted-alternative-for-forbidden-char.conf">Quoted strings may always be used as an alternative
when you need to write a character that is not permitted in an
unquoted string.</mark></p>
<p data-line="258"><mark class="ok" title="unquoted-strings.7 — unquoted-strings/006-truefoo-parses-as-true-then-foo.conf">`truefoo` parses as the boolean token `true` followed by the
unquoted string `foo`.</mark> <mark class="ok" title="unquoted-strings.8 — unquoted-strings/007-footrue-is-one-unquoted-string.conf">However, `footrue` parses as the unquoted
string `footrue`.</mark> <mark class="ok" title="unquoted-strings.9 — unquoted-strings/008-number-then-suffix-string.conf, unquoted-strings/009-digits-not-at-start-stay-string.conf">Similarly, `10.0bar` is the number `10.0` then
string `footrue`.</mark> <mark class="ok" title="unquoted-strings.9 — unquoted-strings/008-number-then-suffix-string.conf, unquoted-strings/009-digits-not-at-start-stay-string.conf, unquoted-strings/022-digit-then-exponent-letter-is-text.conf, unquoted-strings/026-ip-address-is-text.conf, unquoted-strings/027-uuid-is-text.conf">Similarly, `10.0bar` is the number `10.0` then
the unquoted string `bar` but `bar10.0` is the unquoted string
`bar10.0`.</mark> (In practice, this distinction doesn&#x27;t matter much
because of value concatenation; see later section.)</p>
<p data-line="265"><mark class="ok" title="unquoted-strings.10 — unquoted-strings/014-hash-starts-comment-not-forbidden-char-in-string.conf, unquoted-strings/023-unquoted-string-ends-at-end-of-file.conf">In general, once an unquoted string begins, it continues until a
forbidden character or the two-character string &quot;//&quot; is
encountered.</mark> <mark class="ok" title="unquoted-strings.11 — unquoted-strings/010-embedded-null-not-recognized.conf">Embedded (non-initial) booleans, nulls, and numbers
are not recognized as such, they are part of the string.</mark></p>
<p data-line="270"><mark class="ok" title="unquoted-strings.12 — unquoted-strings/012-unquoted-cannot-start-with-hyphen.conf, unquoted-strings/018-leading-dot-is-not-a-number.conf, unquoted-strings/025-digit-initial-invalid-number.conf">An unquoted string may not _begin_ with the digits 0-9 or with a
<p data-line="270"><mark class="ok" title="unquoted-strings.12 — unquoted-strings/012-hyphen-before-a-letter-is-text.conf, unquoted-strings/018-leading-dot-is-not-a-number.conf, unquoted-strings/028-lone-hyphen-is-text.conf, unquoted-strings/029-command-line-flags-are-text.conf, unquoted-strings/030-hyphen-between-words-is-text.conf">An unquoted string may not _begin_ with the digits 0-9 or with a
hyphen (`-`, 0x002D) because those are valid characters to begin a
JSON number.</mark> <mark class="ok" title="unquoted-strings.13 — unquoted-strings/013-negative-number-then-string.conf, unquoted-strings/021-plus-inside-a-number-illegal.conf, unquoted-strings/022-digit-then-exponent-letter-illegal.conf, unquoted-strings/025-digit-initial-invalid-number.conf">The initial number character, plus any valid-in-JSON
JSON number.</mark> <mark class="ok" title="unquoted-strings.13 — unquoted-strings/013-negative-number-then-string.conf, unquoted-strings/021-plus-inside-a-number-illegal.conf, unquoted-strings/025-digit-initial-non-number-is-text.conf">The initial number character, plus any valid-in-JSON
number characters that follow it, must be parsed as a number
value.</mark> Again, these characters are not special _inside_ an
unquoted string; they only trigger number parsing if they appear
Expand Down
Loading
Loading