smarter_json 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/ext/smarter_json/smarter_json.c +12 -8
- data/lib/smarter_json/parser.rb +11 -8
- data/lib/smarter_json/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 004e9e158ab0ec9ac6f7f3e532e01fac5ca525ed0f7409794052b6debbdeaa4e
|
|
4
|
+
data.tar.gz: deaa95b2c671d93db12c3059e79e4ab5908c44f009d5bc843b42b7561c030f7d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b09e63686e0e37ecd25f8a1d511e865bb8f44df2fa95b213e3f5a34d4083ad5b30e0b15ce33c764cdaf960d7f2ebe6a859c8acb3ecdaa49c87118015ef34d88
|
|
7
|
+
data.tar.gz: 3ab34cf983f13f9b5479c69f4764c2cf44ba8da5290c1879b79c9de9338103025a67ab20bd6d6b25a1a5f8029b97868b53e8b8baae4daa430be370c046a222ad
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,14 @@
|
|
|
13
13
|
> ⚠️ We discourage the use of `process(input).first` / `process(input)[0]` because it silently drops potential additional documents
|
|
14
14
|
> Please use `process_one` if you are expecting only one JSON doc, e.g. in API payloads, because it emits on_warning if it finds multiple docs.
|
|
15
15
|
|
|
16
|
+
## 1.2.5 (2026-07-01)
|
|
17
|
+
|
|
18
|
+
RSpec tests: 1,282 → 1,308
|
|
19
|
+
|
|
20
|
+
### New Features
|
|
21
|
+
|
|
22
|
+
- **RFC 7464 JSON Text Sequences are now read natively.** The record separator (`0x1E`) that frames each record is a first-class document separator, so an RS-framed stream parses into its documents without a warning, and bare-scalar records (a number / keyword / string on its own) are read correctly.
|
|
23
|
+
|
|
16
24
|
## 1.2.4 (2026-07-01)
|
|
17
25
|
|
|
18
26
|
RSpec tests: 1,268 → 1,282
|
|
@@ -1624,14 +1624,17 @@ static int fj_implicit_root_ahead(fj_state *st) {
|
|
|
1624
1624
|
return result;
|
|
1625
1625
|
}
|
|
1626
1626
|
|
|
1627
|
-
/* Between top-level documents, whitespace, comments, AND
|
|
1628
|
-
* (commas collapse like the in-container
|
|
1629
|
-
*
|
|
1630
|
-
* the
|
|
1627
|
+
/* Between top-level documents, whitespace, comments, commas, AND the RFC 7464
|
|
1628
|
+
* record separator (0x1E) all separate (commas collapse like the in-container
|
|
1629
|
+
* lenient-comma rule; 0x1E frames each JSON Text Sequence record). A space alone
|
|
1630
|
+
* never separates — that is handled inside the document by the quoteless run.
|
|
1631
|
+
* Mirrors the Ruby Parser#skip_document_separators. */
|
|
1631
1632
|
static void fj_skip_document_separators(fj_state *st) {
|
|
1632
1633
|
for (;;) {
|
|
1634
|
+
int b;
|
|
1633
1635
|
fj_skip_ws_comments(st);
|
|
1634
|
-
|
|
1636
|
+
b = fj_byte(st);
|
|
1637
|
+
if (b != ',' && b != 0x1E) break;
|
|
1635
1638
|
fj_advance(st, 1);
|
|
1636
1639
|
}
|
|
1637
1640
|
}
|
|
@@ -1640,8 +1643,9 @@ static int fj_is_hws(int b) { return b == ' ' || b == '\t' || b == 0x0B || b ==
|
|
|
1640
1643
|
|
|
1641
1644
|
/* After a top-level value: a self-delimiting value (object / array / string) may be
|
|
1642
1645
|
* followed by anything, but a bare scalar (number / keyword) must be followed by a
|
|
1643
|
-
* real separator — a newline, ',',
|
|
1644
|
-
* `1 2 3` and `42 "x" true` raise. Mirrors the
|
|
1646
|
+
* real separator — a newline, ',', the RFC 7464 record separator (0x1E), a comment,
|
|
1647
|
+
* or EOF. A space is NOT a separator, so `1 2 3` and `42 "x" true` raise. Mirrors the
|
|
1648
|
+
* Ruby Parser#enforce_scalar_boundary. */
|
|
1645
1649
|
static void fj_enforce_scalar_boundary(fj_state *st, VALUE value) {
|
|
1646
1650
|
int b, nx;
|
|
1647
1651
|
if (RB_TYPE_P(value, T_STRING) || RB_TYPE_P(value, T_HASH) || RB_TYPE_P(value, T_ARRAY)) return;
|
|
@@ -1655,7 +1659,7 @@ static void fj_enforce_scalar_boundary(fj_state *st, VALUE value) {
|
|
|
1655
1659
|
break;
|
|
1656
1660
|
}
|
|
1657
1661
|
b = fj_byte(st);
|
|
1658
|
-
if (b == -1 || b == 0x0A || b == 0x0D || b == ',') return;
|
|
1662
|
+
if (b == -1 || b == 0x0A || b == 0x0D || b == ',' || b == 0x1E) return;
|
|
1659
1663
|
if (b == '#') return;
|
|
1660
1664
|
if (b == '/') { nx = fj_byte_at(st, 1); if (nx == '/' || nx == '*') return; }
|
|
1661
1665
|
fj_error(st, "a top-level number or keyword must be followed by a newline, ',', or end of input");
|
data/lib/smarter_json/parser.rb
CHANGED
|
@@ -384,6 +384,7 @@ module SmarterJSON
|
|
|
384
384
|
TAB = 0x09
|
|
385
385
|
LF = 0x0A
|
|
386
386
|
CR = 0x0D
|
|
387
|
+
RS = 0x1E # RFC 7464 record separator — frames each JSON Text Sequence record
|
|
387
388
|
end
|
|
388
389
|
|
|
389
390
|
module Framer
|
|
@@ -1052,13 +1053,14 @@ module SmarterJSON
|
|
|
1052
1053
|
parse_iter(implicit_root_object_ahead?)
|
|
1053
1054
|
end
|
|
1054
1055
|
|
|
1055
|
-
# Between top-level documents, whitespace, comments, AND
|
|
1056
|
-
# (commas collapse like the in-container
|
|
1057
|
-
#
|
|
1056
|
+
# Between top-level documents, whitespace, comments, commas, AND the RFC 7464
|
|
1057
|
+
# record separator (0x1E) all separate (commas collapse like the in-container
|
|
1058
|
+
# lenient-comma rule; 0x1E frames each JSON Text Sequence record). A space alone
|
|
1059
|
+
# never separates — that is handled inside the document by the quoteless run, so
|
|
1058
1060
|
# `1 2 3` is one document (the string "1 2 3") while `1, 2, 3` is three.
|
|
1059
1061
|
def skip_document_separators
|
|
1060
1062
|
skip_whitespace_and_comments
|
|
1061
|
-
while byte == COMMA
|
|
1063
|
+
while (b = byte) == COMMA || b == RS
|
|
1062
1064
|
advance(1)
|
|
1063
1065
|
skip_whitespace_and_comments
|
|
1064
1066
|
end
|
|
@@ -1066,15 +1068,16 @@ module SmarterJSON
|
|
|
1066
1068
|
|
|
1067
1069
|
# After a top-level value: a self-delimiting value (object / array / quoted string)
|
|
1068
1070
|
# may be followed by anything (the next document self-delimits), but a bare scalar
|
|
1069
|
-
# (number / keyword) must be followed by a real separator — a newline, ',',
|
|
1070
|
-
# comment, or EOF. A space is NOT a separator, so
|
|
1071
|
-
# rather than silently splitting; bare top-level
|
|
1071
|
+
# (number / keyword) must be followed by a real separator — a newline, ',', the RFC
|
|
1072
|
+
# 7464 record separator (0x1E), a comment, or EOF. A space is NOT a separator, so
|
|
1073
|
+
# `1 2 3` and `42 "x" true` raise rather than silently splitting; bare top-level
|
|
1074
|
+
# words raise in parse_value itself.
|
|
1072
1075
|
def enforce_scalar_boundary(value)
|
|
1073
1076
|
return if value.is_a?(String) || value.is_a?(Hash) || value.is_a?(Array)
|
|
1074
1077
|
|
|
1075
1078
|
skip_horizontal_whitespace
|
|
1076
1079
|
b = byte
|
|
1077
|
-
return if b.nil? || b == LF || b == CR || b == COMMA
|
|
1080
|
+
return if b.nil? || b == LF || b == CR || b == COMMA || b == RS
|
|
1078
1081
|
return if b == HASH || (b == SLASH && ((c = byte_at(1)) == SLASH || c == STAR))
|
|
1079
1082
|
|
|
1080
1083
|
raise error("a top-level number or keyword must be followed by a newline, ',', or end of input")
|
data/lib/smarter_json/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smarter_json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tilo Sloboda
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-07-
|
|
10
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: bigdecimal
|