rb_json5 0.1.0 → 0.2.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: 594540a8d9f462882ebf6af4d8af297efc07c46be1d00c2c02dc2d4b134d8f79
4
- data.tar.gz: 7c3ccdc8e41af153eb5af8ac6bf644dc998067e2a32b1f712091d797c834ef42
3
+ metadata.gz: 81546e53f09d625b4f122a5264f654797e25994cbb2f43a6ec295e2c254ec61d
4
+ data.tar.gz: acf65352e98ab217357718ede345a7574be7a8f84cf07063d5113d92346a69ed
5
5
  SHA512:
6
- metadata.gz: 36cf35e8657d3a60e52afc012b2eba88f9fe19385f64eb56b9a18c8c514b7b54644a79b3893326136c863e8380290cc9e0b310f5609d8163a96aa1780adcaa14
7
- data.tar.gz: 79eef5805af79907cce8fa20db34093dc3b9b57a5ef1f580c405c75ea0c9f28d761727764f02dffa5fc326d5b1f2cd879c1498210391eae93c6645bae381dc25
6
+ metadata.gz: 77a07e83d48962228590d106d33d294dbdc5c02cf8c9b5c08b01e8fc4dd01341a4a6cfc1c682f6ebcc78bf990b3aa404eecc6642fdde2818d1f9f82fe6ec5cf3
7
+ data.tar.gz: b8d9b1425211e63127d195fb191226577203fc543545b8add0afd8a896bdbb98f928884471ba4bc52bef647ccf2fca53ffdf9e7a627f2e204f1ab7d33b98c9e5
data/README.md CHANGED
@@ -48,32 +48,34 @@ json5 = <<~'JSON5'
48
48
  }
49
49
  JSON5
50
50
 
51
- RbJSON5.parse(json5) # =>
52
- # {
53
- # "unquoted"=>"and you can quote me on that",
54
- # "singleQuotes"=>"I can use \"double quotes\" here",
55
- # "lineBreaks"=>"Look, Mom! No \\n's!",
56
- # "hexadecimal"=>912559,
57
- # "leadingDecimalPoint"=>0.8675309,
58
- # "andTrailing"=>8675309.0,
59
- # "positiveSign"=>1,
60
- # "trailingComma"=>"in objects",
61
- # "andIn"=>["arrays"],
62
- # "backwardsCompatible"=>"with JSON"
63
- # }
64
- RbJSON5.parse(json5, symbolize_names: true) # =>
65
- # {
66
- # :unquoted=>"and you can quote me on that",
67
- # :singleQuotes=>"I can use \"double quotes\" here",
68
- # :lineBreaks=>"Look, Mom! No \\n's!",
69
- # :hexadecimal=>912559,
70
- # :leadingDecimalPoint=>0.8675309,
71
- # :andTrailing=>8675309.0,
72
- # :positiveSign=>1,
73
- # :trailingComma=>"in objects",
74
- # :andIn=>["arrays"],
75
- # :backwardsCompatible=>"with JSON"
76
- # }
51
+ RbJSON5.parse(json5)
52
+ # =>
53
+ # {
54
+ # "unquoted"=>"and you can quote me on that",
55
+ # "singleQuotes"=>"I can use \"double quotes\" here",
56
+ # "lineBreaks"=>"Look, Mom! No \\n's!",
57
+ # "hexadecimal"=>912559,
58
+ # "leadingDecimalPoint"=>0.8675309,
59
+ # "andTrailing"=>8675309.0,
60
+ # "positiveSign"=>1,
61
+ # "trailingComma"=>"in objects",
62
+ # "andIn"=>["arrays"],
63
+ # "backwardsCompatible"=>"with JSON"
64
+ # }
65
+ RbJSON5.parse(json5, symbolize_names: true)
66
+ # =>
67
+ # {
68
+ # :unquoted=>"and you can quote me on that",
69
+ # :singleQuotes=>"I can use \"double quotes\" here",
70
+ # :lineBreaks=>"Look, Mom! No \\n's!",
71
+ # :hexadecimal=>912559,
72
+ # :leadingDecimalPoint=>0.8675309,
73
+ # :andTrailing=>8675309.0,
74
+ # :positiveSign=>1,
75
+ # :trailingComma=>"in objects",
76
+ # :andIn=>["arrays"],
77
+ # :backwardsCompatible=>"with JSON"
78
+ # }
77
79
  ```
78
80
 
79
81
  ## Contributing & Contact
@@ -18,16 +18,16 @@ require_relative 'rb_json5/parser/object'
18
18
  module RbJSON5
19
19
  # Parses a JSON5 string into its Ruby data structure
20
20
  #
21
- # @param json5 [String]
22
- # JSON5 string
21
+ # @param string_or_io [String, #read]
22
+ # JSON5 string itself or object like IO containing JSON5 string
23
23
  # @param symbolize_names [Boolean]
24
24
  # If set to true, converts names (keys) in a JSON5 object into Symbol
25
25
  # @return [Object]
26
26
  # Ruby data structure represented by the input
27
27
  #
28
28
  # @see RbJSON5.load_file
29
- def self.parse(json5, symbolize_names: false)
30
- Parser.new.parse(json5, symbolize_names)
29
+ def self.parse(string_or_io, symbolize_names: false)
30
+ Parser.new.parse(string_or_io, symbolize_names)
31
31
  end
32
32
 
33
33
  # Reads a JSON5 string from the given file and parses it into its Ruby data structure
@@ -41,8 +41,6 @@ module RbJSON5
41
41
  #
42
42
  # @see RbJSON5.parse
43
43
  def self.load_file(filename, symbolize_names: false)
44
- File.open(filename, 'r') do |f|
45
- parse(f.read, symbolize_names: symbolize_names)
46
- end
44
+ File.open(filename, 'r') { |io| parse(io, symbolize_names: symbolize_names) }
47
45
  end
48
46
  end
@@ -8,11 +8,16 @@ module RbJSON5
8
8
  # escape sequence
9
9
  # @param valid_patterns [Array<Regexp>]
10
10
  # list of patterns for valid unescaped character
11
- # @param ifinvalid [Proc]
11
+ # @yield [character, sequence]
12
12
  # call back block called when unespaced character is not matched
13
13
  # with the given valid_patterns
14
+ # @yieldparam character [String]
15
+ # character unescaped from the given escape sequence
16
+ # @yieldparam sequence [Parslet::Slice]
17
+ # the given escape sequence
14
18
  def initialize(sequence, valid_patterns = [], &ifinvalid)
15
- @character = unescape(sequence.to_s, valid_patterns, ifinvalid)
19
+ @character = unescape(sequence.to_s)
20
+ validate(@character, sequence, valid_patterns, ifinvalid)
16
21
  end
17
22
 
18
23
  # returns the character unescaped from the given escape sequence
@@ -32,15 +37,17 @@ module RbJSON5
32
37
  '0' => "\0"
33
38
  }.freeze
34
39
 
35
- def unescape(sequence, valid_patterns, ifinvalid)
36
- character =
37
- if ['x', 'u'].include?(sequence[1])
38
- instance_eval("\"#{sequence}\"", __FILE__, __LINE__)
39
- else
40
- ESCAPE_CHARACTERS[sequence[1]] || sequence[1]
41
- end
42
- valid_character?(character, valid_patterns) &&
43
- character || ifinvalid.call(character)
40
+ def unescape(sequence)
41
+ if ['x', 'u'].include?(sequence[1])
42
+ instance_eval("\"#{sequence}\"", __FILE__, __LINE__)
43
+ else
44
+ ESCAPE_CHARACTERS[sequence[1]] || sequence[1]
45
+ end
46
+ end
47
+
48
+ def validate(character, sequence, valid_patterns, ifinvalid)
49
+ valid_character?(character, valid_patterns) ||
50
+ ifinvalid&.call(character, sequence)
44
51
  end
45
52
 
46
53
  def valid_character?(character, valid_patterns)
@@ -54,8 +54,8 @@ module RbJSON5
54
54
  #
55
55
  # @see RbJSON5.parse
56
56
  # @see RbJSON5.load_file
57
- def parse(json5, symbolize_names = false)
58
- tree = parser.parse(json5)
57
+ def parse(string_or_io, symbolize_names = false)
58
+ tree = parser.parse(read_json5(string_or_io))
59
59
  transform.apply(tree, symbolize_names: symbolize_names)
60
60
  rescue Parslet::ParseFailed => e
61
61
  raise ParseError.new(e.message, e.parse_failure_cause)
@@ -63,6 +63,11 @@ module RbJSON5
63
63
 
64
64
  private
65
65
 
66
+ def read_json5(string_or_io)
67
+ string_or_io.respond_to?(:read) &&
68
+ string_or_io.read || string_or_io
69
+ end
70
+
66
71
  def parser
67
72
  parser = self.class.parser.new
68
73
  @root && parser.__send__(@root) || parser
@@ -65,21 +65,21 @@ module RbJSON5
65
65
  empty_object | non_empty_object
66
66
  end
67
67
 
68
- transform_rule(unicode_identifier_start: simple(:sequence)) do
69
- EscapeSequence.new(sequence, IDENTIFIER_START_PATTERNS) do |character|
70
- Parslet::Cause.format(
71
- sequence.line_cache, sequence.position.bytepos,
72
- "#{character.inspect} cannot be used for identifier"
73
- ).raise
74
- end
75
- end
76
-
77
- transform_rule(unicode_identifier_part: simple(:sequence)) do
78
- EscapeSequence.new(sequence, IDENTIFIER_PART_PATTERNS) do |character|
79
- Parslet::Cause.format(
80
- sequence.line_cache, sequence.position.bytepos,
81
- "#{character.inspect} cannot be used for identifier"
82
- ).raise
68
+ # call back block called when character unescaped from Unicode escape sequence
69
+ # is not allowed for identifier
70
+ INVALID_CHARACTER_FOR_IDENTIFIER = lambda do |character, sequence|
71
+ Parslet::Cause.format(
72
+ sequence.line_cache, sequence.position.bytepos,
73
+ "#{character.inspect} cannot be used for identifier"
74
+ ).raise
75
+ end
76
+
77
+ {
78
+ unicode_identifier_start: IDENTIFIER_START_PATTERNS,
79
+ unicode_identifier_part: IDENTIFIER_START_PATTERNS
80
+ }.each do |rule, patterns|
81
+ transform_rule(rule => simple(:sequence)) do
82
+ EscapeSequence.new(sequence, patterns, &INVALID_CHARACTER_FOR_IDENTIFIER)
83
83
  end
84
84
  end
85
85
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module RbJSON5
4
4
  # Current version of RbJSON5
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb_json5
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taichi Ishitani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet