canon 0.3.23 → 0.3.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e3fda4e37d9ca6cf584389c0ffec06c70811ec488910377151ed8ee29f20a35
4
- data.tar.gz: cb73f6f95b16ce10b9ada9f13d1e91eaad0a4bce416d84ddfb49439227f270d5
3
+ metadata.gz: e1d317692d756e058f2a4fb6865fffa4240744ac1b7cf8c83cb026552acb3f16
4
+ data.tar.gz: b993bde4273af1fdfe30d05b43bc0e642b9c3b80d857dc437196d2e7ea20567f
5
5
  SHA512:
6
- metadata.gz: 48a6dacc76c75c234a34583264f0cd3816c643bda7152ccbeee62cb4057fd370c70b168414bca515addc400de5ea12dacb82b9a356d35e4421596bff0109806b
7
- data.tar.gz: a33a5b36fbd98f43d4832dbb275737726f5e9dc1786b91fc34313684a8e431724e3f169a426c18af3d90a15be1fb9a4970e561ef25d2f576ff52229cfebc1829
6
+ metadata.gz: 6ee303aab423e1bfb48b754b441c8e70b307af2a03956bd1cb7c5998dcb575cfc57c9c6ba1d02a22af74717cfbd8aaa1f05b88a52cc698da6e8547e3a0a25ce8
7
+ data.tar.gz: a2de4ba755d59ecd72bfe50e53f6fea6c1136cbc98fda6886c22f5240098a84235d304040dcefb8e1d882a9bab27228f86030bf784b297cbb29df1c745a622af
data/CLAUDE.md CHANGED
@@ -145,7 +145,7 @@ Engine A/B testing: `CANON_XML_BACKEND=nokogiri bundle exec rspec` (or `=moxml`
145
145
 
146
146
  ### YAML Engines
147
147
 
148
- `Canon::YamlBackend` selects the YAML engine: `:psych` (default) or `:yeptris` (FFI over libyeptris, the YAML counterpart of the leptris XML stack — `CANON_YAML_BACKEND=yeptris` opts in; the optional `yeptris` Gemfile group must be enabled). `Canon::YamlParsing` is the single gateway for string loads; `YAML.dump` stays on Psych everywhere — canonical output bytes are canon's product and the writers differ. The default stays `:psych` until the yeptris Psych-parity gaps close (yeptris-ruby#29 empty documents, #30 sexagesimal scalars, #31 >64-bit integers); `spec/canon/yaml_engine_parity_spec.rb` is the executable gate, with upstream-tracked cases pending. Never `require "yeptris/psych"` — it rebinds the global `::Psych` constant for the whole process; only the namespaced `Yeptris::YAML` API is used.
148
+ `Canon::YamlBackend` selects the YAML engine: `:psych` (default) or `:yeptris` (FFI over libyeptris, the YAML counterpart of the leptris XML stack — `CANON_YAML_BACKEND=yeptris` opts in; the optional `yeptris` Gemfile group must be enabled). `Canon::YamlParsing` is the single gateway for string loads; `Canon::JsonParsing` mirrors it for JSON (the same yeptris engine serves both — `Yeptris::YAML.load` auto-detects JSON and routes to the native C-API materializer; JSON falls back to stdlib unless `YamlBackend.yeptris_native?`, since the FFI ladder is ~29x slower than the stdlib C extension). `YAML.dump` stays on Psych everywhere — canonical output bytes are canon's product and the writers differ. The default stays `:psych` until the yeptris Psych-parity gaps close (yeptris-ruby#30 sexagesimal scalars, #31 >64-bit integers — #29 empty documents was fixed in 0.1.12); `spec/canon/yaml_engine_parity_spec.rb` is the executable gate, with upstream-tracked cases pending. Never `require "yeptris/psych"` — it rebinds the global `::Psych` constant for the whole process; only the namespaced `Yeptris::YAML` API is used.
149
149
 
150
150
  ### Format Detection
151
151
 
@@ -64,7 +64,7 @@ module Canon
64
64
  return obj unless obj.is_a?(String)
65
65
 
66
66
  begin
67
- JSON.parse(obj)
67
+ Canon::JsonParsing.parse(obj)
68
68
  rescue JSON::ParserError
69
69
  obj
70
70
  end
@@ -17,7 +17,7 @@ module Canon
17
17
  # Return as-is if already parsed
18
18
  return json if json.is_a?(Hash) || json.is_a?(Array)
19
19
 
20
- JSON.parse(json)
20
+ Canon::JsonParsing.parse(json)
21
21
  end
22
22
 
23
23
  def self.sort_json_keys(obj)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Canon
6
+ # The only place canon talks to a JSON engine. The yeptris fast path
7
+ # (fused C-API materializer, on par with the stdlib C extension)
8
+ # engages through Yeptris::YAML.load's JSON auto-detection; without
9
+ # the native materializer the stdlib parser serves, unchanged.
10
+ # Errors normalize to JSON::ParserError so canon's rescues hold on
11
+ # both engines.
12
+ module JsonParsing
13
+ module_function
14
+
15
+ def parse(json)
16
+ if Canon::YamlBackend.yeptris_native?
17
+ begin
18
+ ::Yeptris::YAML.load(json)
19
+ rescue ::Yeptris::ParseError, ::FFI::NullPointerError => e
20
+ raise JSON::ParserError, e.message
21
+ end
22
+ else
23
+ JSON.parse(json)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -20,7 +20,7 @@ module Canon
20
20
  return if input.is_a?(Hash) || input.is_a?(Array) # Already parsed
21
21
  return if input.strip.empty?
22
22
 
23
- JSON.parse(input)
23
+ Canon::JsonParsing.parse(input)
24
24
  rescue JSON::ParserError => e
25
25
  # Extract position from error message
26
26
  position = extract_position(e.message)
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.23"
4
+ VERSION = "0.3.24"
5
5
  end
@@ -51,6 +51,14 @@ module Canon
51
51
  false
52
52
  end
53
53
 
54
+ # The JSON fast path needs the fused C-API materializer
55
+ # (Yeptris::Native — load_json) specifically: the FFI ladder is
56
+ # ~29x slower than the stdlib JSON C extension, so JSON loads
57
+ # fall back to stdlib when only FFI is present.
58
+ def yeptris_native?
59
+ yeptris? && yeptris_available? && !defined?(::Yeptris::Native).nil?
60
+ end
61
+
54
62
  private
55
63
 
56
64
  def forced
data/lib/canon.rb CHANGED
@@ -7,6 +7,7 @@ require "canon/xml_backend"
7
7
  require "canon/xml_parsing"
8
8
  require "canon/yaml_backend"
9
9
  require "canon/yaml_parsing"
10
+ require "canon/json_parsing"
10
11
  require "canon/config"
11
12
  require "canon/data_model"
12
13
  require "canon/xml"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.23
4
+ version: 0.3.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -332,6 +332,7 @@ files:
332
332
  - lib/canon/html.rb
333
333
  - lib/canon/html/data_model.rb
334
334
  - lib/canon/html/nokogiri_support.rb
335
+ - lib/canon/json_parsing.rb
335
336
  - lib/canon/options.rb
336
337
  - lib/canon/options/cli_generator.rb
337
338
  - lib/canon/options/registry.rb