toml-rb 4.0.0 → 4.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: 7deb039c3dea36679fb813cc6414671f8691f97d8a4d3d180a5a8cab2a5636e8
4
- data.tar.gz: 6d495d33fe92641632e962d560a508c35f1d0f03c5d445e13151b5b4e046a9ce
3
+ metadata.gz: d11cbf4f3f759b946f7f1eec65450c67798690a7488146243e9e524c7f41b0f0
4
+ data.tar.gz: a034e9b52165a77cf56cb33e6fbaae8dc02c64bb9891d0d27b5071490dde7ea2
5
5
  SHA512:
6
- metadata.gz: 853879c8fbd703519d800f6e48b8b81cbc92791adb63584a5be9a75b9f17ea635df63aa86df7c05465684c4d15d2b72528740c307a06abda5f786913391ff16a
7
- data.tar.gz: 766d75b5c583d47a17d17c0fca05d6f520ae198c7953ad78cf2eda937397bb67c77e5c820ca1ea0924825020da3af2d7d26249d89f1a9d6062a03ff647a811dc
6
+ metadata.gz: 0ccb42dd5b8499964d2d0d4b33c2a99b6e5ea1620ca7e8b2c132ccc3e420564c3a897b3075768069c8a82245899cc36eb8e99c2c5f1f2c1723e92f7054f2fc5f
7
+ data.tar.gz: 7cecedebad2b68ee1be63707bce6a7ce8a551356b8a536a6d522d04c38474b0d90c389d2deacfe09a67d206997bc77f472d586f928e9372f7d0ba9b2c899d365
@@ -11,7 +11,7 @@ module TomlRB
11
11
 
12
12
  def initialize(key)
13
13
  @key = key
14
- super "Key #{key.inspect} is defined more than once"
14
+ super("Key #{key.inspect} is defined more than once")
15
15
  end
16
16
  end
17
17
  end
@@ -20,7 +20,7 @@ grammar TomlRB::Document
20
20
  ### Values
21
21
 
22
22
  rule inline_table
23
- (space? '{' (keyvalue? (',' keyvalue)*)? space? '}' ) <TomlRB::InlineTableParser>
23
+ (space? '{' array_comments (keyvalue (array_comments ',' array_comments keyvalue)* (array_comments ',')?)? array_comments '}' ) <TomlRB::InlineTableParser>
24
24
  end
25
25
 
26
26
  rule array
@@ -10,30 +10,36 @@ module TomlRB
10
10
  @symbolize_keys = false
11
11
  end
12
12
 
13
- def assign(hash, fully_defined_keys, symbolize_keys = false)
13
+ def assign(hash, fully_defined_paths, symbolize_keys = false)
14
14
  @symbolize_keys = symbolize_keys
15
- dotted_keys_str = @dotted_keys.join(".")
16
15
  keys = symbolize_keys ? @dotted_keys.map(&:to_sym) : @dotted_keys
16
+ depth = @dotted_keys.size
17
17
  update = keys.reverse.inject(visit_value(@value)) { |k1, k2| {k2 => k1} }
18
18
 
19
+ parent_inline_table = fully_defined_paths.find { |k| k.size < depth && @dotted_keys.first(k.size) == k }
20
+ fail ValueOverwriteError.new(@dotted_keys.first) if parent_inline_table
21
+
19
22
  if @value.is_a?(InlineTable)
20
- fully_defined_keys << dotted_keys_str
21
- hash.merge!(update) { |key, _, _| fail ValueOverwriteError.new(key) }
22
- elsif fully_defined_keys.find { |k| update.dig(*k) }
23
- hash.merge!(update) { |key, _, _| fail ValueOverwriteError.new(key) }
24
- else
25
- dotted_key_merge(hash, update)
23
+ child_keys_exist = fully_defined_paths.find { |k| k.size > depth && k.first(depth) == @dotted_keys }
24
+ fail ValueOverwriteError.new(@dotted_keys.first) if child_keys_exist
25
+
26
+ existing_hash = hash.dig(*keys)
27
+ fail ValueOverwriteError.new(@dotted_keys.first) if existing_hash.is_a?(Hash) && !existing_hash.empty?
28
+
29
+ fully_defined_paths << @dotted_keys
26
30
  end
31
+
32
+ dotted_key_merge(hash, update)
27
33
  end
28
34
 
29
35
  def dotted_key_merge(hash, update)
30
- hash.merge!(update) { |key, old, new|
36
+ hash.merge!(update) do |key, old, new|
31
37
  if old.is_a?(Hash) && new.is_a?(Hash)
32
38
  dotted_key_merge(old, new)
33
39
  else
34
40
  fail ValueOverwriteError.new(key)
35
41
  end
36
- }
42
+ end
37
43
  end
38
44
 
39
45
  def accept_visitor(parser)
@@ -5,7 +5,7 @@ module TomlRB
5
5
  def initialize(content, symbolize_keys: false)
6
6
  @hash = {}
7
7
  @visited_keys = []
8
- @fully_defined_keys = []
8
+ @fully_defined_paths = []
9
9
  @current = @hash
10
10
  @symbolize_keys = symbolize_keys
11
11
 
@@ -14,13 +14,21 @@ module TomlRB
14
14
  parsed.matches.map(&:value).compact.each { |m| m.accept_visitor(self) }
15
15
  rescue Citrus::ParseError => e
16
16
  raise TomlRB::ParseError.new(e.message)
17
+ rescue Encoding::CompatibilityError => e
18
+ raise TomlRB::ParseError.new("Encoding error: #{e.message}")
19
+ rescue ArgumentError => e
20
+ if e.message.include?("invalid byte sequence") || e.message.include?("encoding")
21
+ raise TomlRB::ParseError.new("Encoding error: #{e.message}")
22
+ else
23
+ raise
24
+ end
17
25
  end
18
26
  end
19
27
 
20
28
  # Read about the Visitor pattern
21
29
  # http://en.wikipedia.org/wiki/Visitor_pattern
22
30
  def visit_table_array(table_array)
23
- @fully_defined_keys = []
31
+ @fully_defined_paths = []
24
32
  table_array_key = table_array.full_key
25
33
  @visited_keys.reject! { |k| k.start_with? table_array_key }
26
34
 
@@ -28,12 +36,12 @@ module TomlRB
28
36
  end
29
37
 
30
38
  def visit_table(table)
31
- @fully_defined_keys = []
39
+ @fully_defined_paths = []
32
40
  @current = table.navigate_keys @hash, @visited_keys, @symbolize_keys
33
41
  end
34
42
 
35
43
  def visit_keyvalue(keyvalue)
36
- keyvalue.assign @current, @fully_defined_keys, @symbolize_keys
44
+ keyvalue.assign @current, @fully_defined_paths, @symbolize_keys
37
45
  end
38
46
  end
39
47
  end
data/lib/toml-rb/table.rb CHANGED
@@ -8,9 +8,16 @@ module TomlRB
8
8
  ensure_key_not_defined(visited_keys)
9
9
  current = hash
10
10
  keys = symbolize_keys ? @dotted_keys.map(&:to_sym) : @dotted_keys
11
- keys.each do |key|
11
+ keys.each_with_index do |key, index|
12
12
  current[key] = {} unless current.key?(key)
13
13
  element = current[key]
14
+
15
+ # If this is the final key and it's already an array (from [[key]]), that's invalid
16
+ is_final_key = (index == keys.length - 1)
17
+ if is_final_key && element.is_a?(Array)
18
+ fail ValueOverwriteError.new(key)
19
+ end
20
+
14
21
  current = element.is_a?(Array) ? element.last : element
15
22
  # check that key has not been defined before as a scalar value
16
23
  fail ValueOverwriteError.new(key) unless current.is_a?(Hash)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TomlRB
4
- VERSION = "4.0.0"
4
+ VERSION = "4.2.0"
5
5
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toml-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emiliano Mancuso
8
8
  - Lucas Tolchinsky
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2025-03-12 00:00:00.000000000 Z
11
+ date: 2026-04-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: citrus
@@ -116,7 +115,6 @@ homepage: https://github.com/emancu/toml-rb
116
115
  licenses:
117
116
  - MIT
118
117
  metadata: {}
119
- post_install_message:
120
118
  rdoc_options: []
121
119
  require_paths:
122
120
  - lib
@@ -124,15 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
122
  requirements:
125
123
  - - ">="
126
124
  - !ruby/object:Gem::Version
127
- version: '2.3'
125
+ version: '2.5'
128
126
  required_rubygems_version: !ruby/object:Gem::Requirement
129
127
  requirements:
130
128
  - - ">="
131
129
  - !ruby/object:Gem::Version
132
130
  version: '0'
133
131
  requirements: []
134
- rubygems_version: 3.1.6
135
- signing_key:
132
+ rubygems_version: 3.6.2
136
133
  specification_version: 4
137
134
  summary: Toml parser in ruby, for ruby.
138
135
  test_files: []