toml-rb 4.1.0 → 4.2.1

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: 80597ee120e2f6517bfca775d9215d4ac3c9c9880bac87c1ec432edb78f32566
4
- data.tar.gz: fd278770b1c245508fc7ceb15336fba968e98b258bc06badcca0875107406292
3
+ metadata.gz: 6d198202b34da88436ce3d0e3cb8841bc1a6ff433a0d9397303c0870c6fed1d5
4
+ data.tar.gz: 916c15730aebc6974a1e7fd04e7c793a3b1321312657f370cae8c9c0a63e6f54
5
5
  SHA512:
6
- metadata.gz: d31002d86304f9c675da476e41f9c196077c7ded480f9f2224fb9d43416de1964238410828d55ce894f0ed68a0559097f2d96324be0f527771507f2589da4777
7
- data.tar.gz: 91a114c7a2c397be72edfb826025ae1cde65d0732359c38a3719ca6e61f2cd6eb237842d7ddf60e3034db9791c800c916e8bf1885aaa48e56ff147aaccc68d20
6
+ metadata.gz: acf22dc79ffa1f4b4650e1979eaf7b3d3a04bc894c68e752008e87dbdf695d5ab4ad2c4e835b8d7a5b0aab151c802cd6cfc403ecd361a2cad125c32cf2cb42b3
7
+ data.tar.gz: 1bdedac516138288dcb97ce4cf59153d03d5fdc8f48a93eca7afbd3ab2931f9ca1dd73eb104decca1e1a6bc7dbc3771d575cfe6a81429e3590e3f41d4048c959
data/README.md CHANGED
@@ -68,6 +68,22 @@ TomlRB.dump(hash)
68
68
  # => "title = \"wow!\"\n[awesome]\nothers = false\nyou = true\n"
69
69
  ```
70
70
 
71
+ Conformance
72
+ -----------
73
+
74
+ `toml-rb` is exercised against the official
75
+ [toml-test](https://github.com/toml-lang/toml-test) conformance suite for both
76
+ TOML 1.0.0 and TOML 1.1.0. The harness lives in:
77
+
78
+ - `tool/toml-test-decoder` — toml-test decoder shim.
79
+ - `.github/workflows/conformance.yml` — CI workflow (per-version matrix).
80
+ - `.github/toml-test-skip-1.0.txt` and `.github/toml-test-skip-1.1.txt` —
81
+ skip-lists of currently-failing tests.
82
+
83
+ The skip-lists are a living gap report: every entry is a known limitation in
84
+ the current parser. The goal for v5.0.0 is **empty skip-lists** — full
85
+ conformance against both spec versions.
86
+
71
87
  Contributing
72
88
  ------------
73
89
 
@@ -4,6 +4,18 @@ require "date"
4
4
 
5
5
  module TomlRB
6
6
  class Dumper
7
+ # TOML basic strings only allow these short escapes; every other control
8
+ # character must be written as \uXXXX (TOML 1.0.0 spec).
9
+ BASIC_ESCAPES = {
10
+ "\\" => "\\\\",
11
+ "\"" => "\\\"",
12
+ "\b" => "\\b",
13
+ "\t" => "\\t",
14
+ "\n" => "\\n",
15
+ "\f" => "\\f",
16
+ "\r" => "\\r"
17
+ }.freeze
18
+
7
19
  attr_reader :toml_str
8
20
 
9
21
  def initialize(hash)
@@ -96,25 +108,40 @@ module TomlRB
96
108
  elsif obj.is_a?(Regexp)
97
109
  obj.inspect.inspect
98
110
  elsif obj.is_a?(String)
99
- obj.inspect.gsub(/\\(#[$@{])/, '\1')
111
+ escape_string(obj)
100
112
  elsif obj.is_a?(Array)
101
113
  "[" + obj.map(&method(:to_toml)).join(", ") + "]"
114
+ elsif obj.is_a?(Float) && (obj.nan? || obj.infinite?)
115
+ # Ruby renders these as Infinity/-Infinity/NaN, which are invalid TOML.
116
+ if obj.nan?
117
+ "nan"
118
+ elsif obj.negative?
119
+ "-inf"
120
+ else
121
+ "inf"
122
+ end
102
123
  else
103
124
  obj.inspect
104
125
  end
105
126
  end
106
127
 
107
128
  def bare_key?(key)
108
- !!key.to_s.match(/^[a-zA-Z0-9_-]+$/)
129
+ !!key.to_s.match(/\A[a-zA-Z0-9_-]+\z/)
109
130
  end
110
131
 
111
- # The key needs to use quotes according to TOML specs.
112
- # Ruby representation of literals or strings, mixed with special characters
113
- # made the concatenation error-prone, luckiley the `#inspect` method returns
114
- # exactly what we need. I decided to keep the method `quote_key/1`
115
- # for readability.
132
+ # Quote and escape a key as a TOML basic string.
116
133
  def quote_key(key)
117
- key.inspect
134
+ escape_string(key.to_s)
135
+ end
136
+
137
+ # Serialize a Ruby string as a TOML basic string. Ruby's String#inspect
138
+ # emits \a \v \e for 0x07/0x0B/0x1B, which TOML (and this parser) reject.
139
+ def escape_string(str)
140
+ escaped = str.gsub(/[\x00-\x1f\x7f"\\]/) do |char|
141
+ BASIC_ESCAPES[char] || format('\\u%04X', char.ord)
142
+ end
143
+
144
+ "\"#{escaped}\""
118
145
  end
119
146
  end
120
147
  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,23 +10,23 @@ 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_keys.find { |k| dotted_keys_str.start_with?("#{k}.") }
19
+ parent_inline_table = fully_defined_paths.find { |k| k.size < depth && @dotted_keys.first(k.size) == k }
20
20
  fail ValueOverwriteError.new(@dotted_keys.first) if parent_inline_table
21
21
 
22
22
  if @value.is_a?(InlineTable)
23
- child_keys_exist = fully_defined_keys.find { |k| k.start_with?("#{dotted_keys_str}.") }
23
+ child_keys_exist = fully_defined_paths.find { |k| k.size > depth && k.first(depth) == @dotted_keys }
24
24
  fail ValueOverwriteError.new(@dotted_keys.first) if child_keys_exist
25
25
 
26
26
  existing_hash = hash.dig(*keys)
27
27
  fail ValueOverwriteError.new(@dotted_keys.first) if existing_hash.is_a?(Hash) && !existing_hash.empty?
28
28
 
29
- fully_defined_keys << dotted_keys_str
29
+ fully_defined_paths << @dotted_keys
30
30
  end
31
31
 
32
32
  dotted_key_merge(hash, update)
@@ -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
 
@@ -28,7 +28,7 @@ module TomlRB
28
28
  # Read about the Visitor pattern
29
29
  # http://en.wikipedia.org/wiki/Visitor_pattern
30
30
  def visit_table_array(table_array)
31
- @fully_defined_keys = []
31
+ @fully_defined_paths = []
32
32
  table_array_key = table_array.full_key
33
33
  @visited_keys.reject! { |k| k.start_with? table_array_key }
34
34
 
@@ -36,12 +36,12 @@ module TomlRB
36
36
  end
37
37
 
38
38
  def visit_table(table)
39
- @fully_defined_keys = []
39
+ @fully_defined_paths = []
40
40
  @current = table.navigate_keys @hash, @visited_keys, @symbolize_keys
41
41
  end
42
42
 
43
43
  def visit_keyvalue(keyvalue)
44
- keyvalue.assign @current, @fully_defined_keys, @symbolize_keys
44
+ keyvalue.assign @current, @fully_defined_paths, @symbolize_keys
45
45
  end
46
46
  end
47
47
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TomlRB
4
- VERSION = "4.1.0"
4
+ VERSION = "4.2.1"
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.1.0
4
+ version: 4.2.1
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-10-29 00:00:00.000000000 Z
11
+ date: 2026-07-31 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: []