json_scanner 0.1.1 → 0.3.0

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: 1ffddd81459c088040c2ddee0006b1c9172e8a15aa8bab987dc59743e697f49f
4
- data.tar.gz: 73b69bbcddaaf6711b2563787c4cbde1d258bf1d28b1e694714fd782c42d4c2c
3
+ metadata.gz: 9c1ddff519827bc802cdcacb5b048402706544b0882c8ac91cd1aa414c4b57e0
4
+ data.tar.gz: d1c4f41dbd71ed08a488c2f9647194fd2692c91d522fee35d28d7060bf80321c
5
5
  SHA512:
6
- metadata.gz: 44a153e578da606f67399a09387cf26d63b1528ad9e6bb258083435202f094ebc95e3a2c895a83334eb2aeef4ea9bfbe0f0c38374ac76f5772beea6bc3910a0f
7
- data.tar.gz: ff9bcbc934fafc4857faf926bca5f5c6c82ec357107b8d6e5f2c0a7e9e622afe3a19d4b0a3f4a987d2e965432c73615203afd1c3e1ac6a52965555b20ef2f377
6
+ metadata.gz: 57bf59cc9495f46675bb98d2fc7545bdc3b8392631c443ad2b89595b22be054c8f8bb268a798c5f104d1e38b73d577662f96637fd9311260c9b0a45b55044265
7
+ data.tar.gz: '055432559a23dbf34e679aac7be4967ea163684fda718b433e978c34feb73f298f1346b00629fada8279a9e49e1267b990f73d2d57c8403330faf42ce4086bb8'
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # JsonScanner
4
4
 
5
- Extract values from JSON without full parsing. This gem uses yajl lib to scan a json string and allows you to parse pieces of it.
5
+ Extract values from JSON without full parsing. This gem uses the `yajl` library to scan a JSON string and allows you to parse pieces of it.
6
6
 
7
7
  ## Installation
8
8
 
@@ -16,6 +16,8 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
16
 
17
17
  ## Usage
18
18
 
19
+ Basic usage
20
+
19
21
  ```ruby
20
22
  require "json"
21
23
  require "json_scanner"
@@ -32,13 +34,77 @@ emoji_json = '{"grin": "😁", "heart": "😍", "rofl": "🤣"}'
32
34
  begin_pos, end_pos, = JsonScanner.scan(emoji_json, [["heart"]], false).first.first
33
35
  emoji_json.byteslice(begin_pos...end_pos)
34
36
  # => "\"😍\""
35
- # Note: most likely don't need `quirks_mode` option, unless you are using some old ruby
36
- # with stdlib version of json gem or its old version. In new versions `quirks_mode` is default
37
+ # Note: You most likely don't need the `quirks_mode` option unless you are using an older version
38
+ # of Ruby with the stdlib - or just also old - version of the json gem. In newer versions, `quirks_mode` is enabled by default.
37
39
  JSON.parse(emoji_json.byteslice(begin_pos...end_pos), quirks_mode: true)
38
40
  # => "😍"
39
41
  # You can also do this
40
42
  # emoji_json.force_encoding(Encoding::BINARY)[begin_pos...end_pos].force_encoding(Encoding::UTF_8)
41
43
  # => "\"😍\""
44
+
45
+ # Ranges are supported as matchers for indexes with the following restrictions:
46
+ # - the start of a range must be positive
47
+ # - the end of a range must be positive or -1
48
+ # - a range with -1 end must be closed, e.g. (0..-1) works, but (0...-1) is forbidden
49
+ JsonScanner.scan('[0, 42, 0]', [[(1..-1)]])
50
+ # => [[[4, 6, :number], [8, 9, :number]]]
51
+ JsonScanner.scan('[0, 42, 0]', [[JsonScanner::ANY_INDEX]])
52
+ # => [[[1, 2, :number], [4, 6, :number], [8, 9, :number]]]
53
+
54
+ # Special matcher JsonScanner::ANY_KEY is supported for object keys
55
+ JsonScanner.scan('{"a": 1, "b": 2}', [[JsonScanner::ANY_KEY]], with_path: true)
56
+ # => [[[["a"], [6, 7, :number]], [["b"], [14, 15, :number]]]]
57
+ ```
58
+
59
+ It supports multiple options
60
+
61
+ ```ruby
62
+ JsonScanner.scan('[0, 42, 0]', [[(1..-1)]], with_path: true)
63
+ # => [[[[1], [4, 6, :number]], [[2], [8, 9, :number]]]]
64
+ JsonScanner.scan('[0, 42,', [[(1..-1)]], verbose_error: true)
65
+ # JsonScanner::ParseError (parse error: premature EOF)
66
+ # [0, 42,
67
+ # (right here) ------^
68
+ JsonScanner.scan('[0, /* answer */ 42, 0]', [[(1..-1)]], allow_comments: true)
69
+ # => [[[17, 19, :number], [21, 22, :number]]]
70
+ JsonScanner.scan("\"\x81\x83\"", [[]], dont_validate_strings: true)
71
+ # => [[[0, 4, :string]]]
72
+ JsonScanner.scan("{\"\x81\x83\": 42}", [[JsonScanner::ANY_KEY]], dont_validate_strings: true, with_path: true)
73
+ # => [[[["\x81\x83"], [7, 9, :number]]]]
74
+ JsonScanner.scan('[0, 42, 0]garbage', [[(1..-1)]], allow_trailing_garbage: true)
75
+ # => [[[4, 6, :number], [8, 9, :number]]]
76
+ JsonScanner.scan('[0, 42, 0] [0, 34]', [[(1..-1)]], allow_multiple_values: true)
77
+ # => [[[4, 6, :number], [8, 9, :number], [16, 18, :number]]]
78
+ JsonScanner.scan('[0, 42, 0', [[(1..-1)]], allow_partial_values: true)
79
+ # => [[[4, 6, :number], [8, 9, :number]]]
80
+ JsonScanner.scan('{"a": 1}', [[JsonScanner::ANY_KEY]], with_path: true, symbolize_path_keys: true)
81
+ # => [[[[:a], [6, 7, :number]]]]
82
+ ```
83
+
84
+ Note that the standard `JSON` library supports comments, so you may want to enable it in the `JsonScanner` as well
85
+ ```ruby
86
+ json_str = '{"answer": {"value": 42 /* the Ultimate Question of Life, the Universe, and Everything */ }}'
87
+ JsonScanner.scan(json_str, [["answer"]], allow_comments: true).first.map do |begin_pos, end_pos, _type|
88
+ JSON.parse(json_str.byteslice(begin_pos...end_pos), quirks_mode: true)
89
+ end
90
+ # => [{"value"=>42}]
91
+ ```
92
+
93
+ You can also create a config and reuse it
94
+
95
+ ```ruby
96
+ require "json_scanner"
97
+
98
+ config = JsonScanner::Config.new([[], ["key"], [(0..-1)]])
99
+ # => #<JsonScanner::Config [[], ['key'], [(0..9223372036854775807)]]>
100
+ JsonScanner.scan('{"key": "42"}', config)
101
+ # => [[[0, 13, :object]], [[8, 12, :string]], []]
102
+ JsonScanner.scan('{"key": "42"}', config, with_path: true)
103
+ # => [[[[], [0, 13, :object]]], [[["key"], [8, 12, :string]]], []]
104
+ JsonScanner.scan('[0, 42]', config)
105
+ # => [[[0, 7, :array]], [], [[1, 2, :number], [4, 6, :number]]]
106
+ JsonScanner.scan('[0, 42]', config, with_path: true)
107
+ # => [[[[], [0, 7, :array]]], [], [[[0], [1, 2, :number]], [[1], [4, 6, :number]]]]
42
108
  ```
43
109
 
44
110
  ## Development