toml_empty 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 18f7758393bd1544a64b10d28ab7a83340f07c14d90a2e6177b362abd43debea
4
+ data.tar.gz: 89879113263d7ecd003a6f0b950dcfe1657d45a5296532a711ff82285c249e37
5
+ SHA512:
6
+ metadata.gz: 45613e3e99d0123782583bdcf4fe98e010353e52b33519da766a9bb5e9ee9e41ccb9dac5ff492467fb4c28f5a22b71e37c6180c3bcf905e2e6d554f9c39a3a9a
7
+ data.tar.gz: fbbb621d8725790a55aad4da7b355c301fd0f0869ffa77b20d05dd6b56dbe48eeb7c527117933347f23d11c314098f2b609d483e8e2dcaefc31ce179ae221740
data/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ ## 0.3.0 / 2020-06-09
2
+
3
+ - Fixes TOML to work with version 2.0 of Parslet
4
+
5
+ ## 0.2.0 / 2017-11-11
6
+
7
+ - Add support for underscored Integers and Floats
8
+ - Fixes TOML to work with version 1.8.0 of Parslet
9
+
10
+ ## 0.1.2 / 2014-10-16
11
+
12
+ - Add support for `CR` and `CRLF` newlines (#13)
13
+ - Add support for generating TOML from Ruby `Hash`es (#36)
14
+ - Add a script interface for @BurntSushi's `toml-test` utility (#38)
15
+
16
+ ## 0.1.1 / 2014-02-17
17
+
18
+ - Add license to gemspec (#26)
19
+ - Loosen `multi_json` dependency version specified (#27)
20
+ - `Generator` should print empty hash tables but not keys without values (#28)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) Tom Preston-Werner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # TOML
2
+
3
+ A sane configuration format from @mojombo. More information here: https://github.com/mojombo/toml
4
+
5
+ This is far superior to YAML and JSON because it doesn't suck. Really it doesn't.
6
+
7
+ ## Usage
8
+
9
+ Add to your Gemfile:
10
+
11
+ ```ruby
12
+ gem "toml", "~> 0.3.0"
13
+ ```
14
+
15
+ It's simple, really.
16
+
17
+ ```ruby
18
+ content = <<-TOML
19
+
20
+ # Hello, this is an example.
21
+ [things]
22
+ other = "things"
23
+ what = 900000
24
+
25
+ TOML
26
+
27
+ parser = TOML::Parser.new(content).parsed
28
+ # => { "things" => { "other" => "things", "what" => 900000 } }
29
+ ```
30
+
31
+ You can also use the same API as `YAML` if you'd like:
32
+
33
+ ```ruby
34
+ TOML.load("thing = 9")
35
+ # => {"thing" => 9}
36
+
37
+ TOML.load_file("my_file.toml")
38
+ # => {"whatever" => "keys"}
39
+ ```
40
+
41
+ There's also a beta feature for generating a TOML file from a Ruby hash. Please note this will likely not give beautiful output right now.
42
+
43
+ ```ruby
44
+ hash = {
45
+ "integer" => 1,
46
+ "float" => 3.14159,
47
+ "true" => true,
48
+ "false" => false,
49
+ "string" => "hi",
50
+ "array" => [[1], [2], [3]],
51
+ "key" => {
52
+ "group" => {
53
+ "value" => "lol"
54
+ }
55
+ }
56
+ }
57
+ doc = TOML::Generator.new(hash).body
58
+ # doc will be a string containing a proper TOML document.
59
+ ```
60
+
61
+ ## Contributors
62
+
63
+ Written by Jeremy McAnally (@jm) and Dirk Gadsden (@dirk) based on TOML from Tom Preston-Werner (@mojombo).
data/lib/toml.rb ADDED
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'time'
4
+ require 'parslet'
5
+
6
+ require 'toml/version'
7
+ require 'toml/key'
8
+ require 'toml/table'
9
+ require 'toml/parslet'
10
+ require 'toml/transformer'
11
+ require 'toml/parser'
12
+ require 'toml/generator'
13
+ # Don't do monkey-patching by default. Only pulled in by TOML::Generator
14
+ # if needed (see generator.rb line 27).
15
+ # require 'toml/monkey_patch
16
+
17
+ module TOML
18
+ def self.load(content)
19
+ Parser.new(content).parsed
20
+ end
21
+
22
+ def self.load_file(path)
23
+ Parser.new(File.read(path)).parsed
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module TOML
3
+ class Generator
4
+ attr_reader :body, :doc
5
+
6
+ def initialize(doc)
7
+ # Ensure all the to_toml methods are injected into the base Ruby classes
8
+ # used by TOML.
9
+ self.class.inject!
10
+
11
+ @doc = doc
12
+ @body = doc.to_toml
13
+
14
+ return @body
15
+ end
16
+
17
+ # Whether or not the injections have already been done.
18
+ @@injected = false
19
+ # Inject to_toml methods into the Ruby classes used by TOML (booleans,
20
+ # String, Numeric, Array). You can add to_toml methods to your own classes
21
+ # to allow them to be easily serialized by the generator (and it will shout
22
+ # if something doesn't have a to_toml method).
23
+ def self.inject!
24
+ return if @@injected
25
+ require 'toml/monkey_patch'
26
+ @@injected = true
27
+ end
28
+ end#Generator
29
+ end#TOML
data/lib/toml/key.rb ADDED
@@ -0,0 +1,10 @@
1
+ module TOML
2
+ class Key
3
+ attr_reader :key, :value
4
+
5
+ def initialize(key, value)
6
+ @key = key
7
+ @value = value
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,89 @@
1
+ # Adds to_toml methods to base Ruby classes used by the generator.
2
+ class Object
3
+ def toml_table?
4
+ self.kind_of?(Hash)
5
+ end
6
+ def toml_table_array?
7
+ self.kind_of?(Array) && self.first.toml_table?
8
+ end
9
+ end
10
+ class Hash
11
+ def to_toml(path = "")
12
+ return "" if self.empty?
13
+
14
+ tables = {}
15
+ values = {}
16
+ self.keys.sort.each do |key|
17
+ val = self[key]
18
+ if val.kind_of?(NilClass)
19
+ next
20
+ elsif val.toml_table? || val.toml_table_array?
21
+ tables[key] = val
22
+ else
23
+ values[key] = val
24
+ end
25
+ end
26
+
27
+ toml = ""
28
+ values.each do |key, val|
29
+ toml << "#{key} = #{val.to_toml(key)}\n"
30
+ end
31
+
32
+ tables.each do |key, val|
33
+ key = "#{path}.#{key}" unless path.empty?
34
+ toml_val = val.to_toml(key)
35
+ if toml_val.empty?
36
+ toml << "\n[#{key}]\n"
37
+ else
38
+ if val.toml_table?
39
+ non_table_vals = val.values.reject do |v|
40
+ v.toml_table? || v.toml_table_array?
41
+ end
42
+
43
+ # Only add the table key if there are non table values.
44
+ if non_table_vals.length > 0
45
+ toml << "\n[#{key}]\n"
46
+ end
47
+ end
48
+ toml << toml_val
49
+ end
50
+ end
51
+
52
+ toml
53
+ end
54
+ end
55
+ class Array
56
+ def to_toml(path = "")
57
+ unless self.map(&:class).uniq.length == 1
58
+ raise "All array values must be the same type"
59
+ end
60
+
61
+ if self.first.toml_table?
62
+ toml = ""
63
+ self.each do |val|
64
+ toml << "\n[[#{path}]]\n"
65
+ toml << val.to_toml(path)
66
+ end
67
+ return toml
68
+ else
69
+ "[" + self.map {|v| v.to_toml(path) }.join(",") + "]"
70
+ end
71
+ end
72
+ end
73
+ class TrueClass
74
+ def to_toml(path = ""); "true"; end
75
+ end
76
+ class FalseClass
77
+ def to_toml(path = ""); "false"; end
78
+ end
79
+ class String
80
+ def to_toml(path = ""); self.inspect; end
81
+ end
82
+ class Numeric
83
+ def to_toml(path = ""); self.to_s; end
84
+ end
85
+ class DateTime
86
+ def to_toml(path = "")
87
+ self.to_time.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
88
+ end
89
+ end
@@ -0,0 +1,99 @@
1
+ module TOML
2
+ class Parser
3
+ attr_reader :parsed
4
+
5
+ def initialize(markup)
6
+ # Make sure we have a newline on the end
7
+
8
+ markup += "\n" unless markup.end_with?("\n") || markup.length == 0
9
+ begin
10
+ tree = Parslet.new.parse(markup)
11
+ rescue Parslet::ParseFailed => failure
12
+ puts failure.cause.ascii_tree
13
+ end
14
+
15
+
16
+ parts = Transformer.new.apply(tree) || []
17
+ @parsed = {}
18
+ @current = @parsed
19
+ @current_path = ''
20
+
21
+ parts.each do |part|
22
+ if part.is_a? Key
23
+ # If @current is an array then we're in a key-group
24
+ if @current.is_a? Array
25
+ # Make sure there's a table to work with.
26
+ @current << {} if @current.last.nil?
27
+ # Set the key on the table.
28
+ @current.last[part.key] = part.value
29
+ next
30
+ end
31
+ # Make sure the key isn't already set
32
+ if !@current.is_a?(Hash) || @current.has_key?(part.key)
33
+ err = "Cannot override key '#{part.key}'"
34
+ unless @current_path.empty?
35
+ err += " at path '#{@current_path}'"
36
+ end
37
+ raise err
38
+ end
39
+ # Set the key-value into the current hash
40
+ @current[part.key] = part.value
41
+ elsif part.is_a?(TableArray)
42
+ resolve_table_array(part)
43
+ elsif part.is_a?(Table)
44
+ resolve_table(part)
45
+ else
46
+ raise "Unrecognized part: #{part.inspect}"
47
+ end
48
+ end
49
+ end
50
+
51
+ def resolve_table_array(t)
52
+ @current = @parsed
53
+ path = t.name.dup
54
+ @current_path = path.join('.')
55
+ while n = path.shift
56
+ # If it's a table-array then get the last item.
57
+ @current = @current.last if @current.is_a? Array
58
+
59
+ # If it's the last item:
60
+ if path.length == 0
61
+ # If the current table has an item:
62
+ if @current.has_key?(n)
63
+ # And that item is already a table-array:
64
+ if @current[n].is_a? Array
65
+ # Then add an item to that table-array.
66
+ @current[n] << {}
67
+ else
68
+ raise "Cannot override table array '#{t.name.join '.'}'"
69
+ end
70
+ else
71
+ # Create a new table array if nothing exists here.
72
+ @current[n] = []
73
+ end
74
+ elsif @current.has_key? n
75
+ # Don't do anything if we're just moving into tables.
76
+ else
77
+ @current[n] = {}
78
+ end
79
+ @current = @current[n]
80
+ end
81
+ end
82
+
83
+ def resolve_table(t)
84
+ @current = @parsed
85
+
86
+ path = t.name.dup
87
+ @current_path = path.join('.')
88
+ while k = path.shift
89
+ # If it's a table-array then get the last item.
90
+ @current = @current.last if @current.is_a? Array
91
+ # Create a new table if one doesn't exist.
92
+ @current[k] = {} if !@current.has_key? k
93
+ # Move into the table.
94
+ @current = @current[k]
95
+ end
96
+ end#/resolve_key_group
97
+
98
+ end
99
+ end
@@ -0,0 +1,103 @@
1
+ module TOML
2
+ class Parslet < ::Parslet::Parser
3
+ rule(:document) {
4
+ all_space >>
5
+ (table | table_array | key_value | comment_line).repeat >>
6
+ all_space
7
+ }
8
+ root :document
9
+
10
+ rule(:value) {
11
+ array |
12
+ string |
13
+ datetime.as(:datetime) |
14
+ float.as(:float) |
15
+ integer.as(:integer) |
16
+ boolean
17
+ }
18
+
19
+ # Finding comments in multiline arrays requires accepting a bunch of
20
+ # possible newlines and stuff before the comment
21
+ rule(:array_comments) { (all_space >> comment_line).repeat }
22
+
23
+ rule(:array) {
24
+ str("[") >> all_space >> array_comments >>
25
+ ( array_comments >> # Match any comments on first line
26
+ all_space >> value >> array_comments >>
27
+ (
28
+ # Separator followed by any comments
29
+ all_space >> str(",") >> array_comments >>
30
+ # Value followed by any comments
31
+ all_space >> value >> array_comments
32
+ ).repeat >>
33
+ (all_space >> str(",")).maybe >> # possible trailing comma
34
+ all_space >> array_comments # Grab any remaining comments just in case
35
+ ).maybe.as(:array) >> str("]")
36
+ }
37
+
38
+ rule(:key_value) {
39
+ space >> key.as(:key) >>
40
+ space >> str("=") >>
41
+ space >> value.as(:value) >>
42
+ space >> comment.maybe >> newline >> all_space
43
+ }
44
+ rule(:table) {
45
+ space >> str("[") >>
46
+ table_name.as(:table) >>
47
+ str("]") >>
48
+ space >> comment.maybe >> newline >> all_space
49
+ }
50
+ rule(:table_array) {
51
+ space >> str("[[") >>
52
+ table_name.as(:table_array) >>
53
+ str("]]") >>
54
+ space >> comment.maybe >> str("\n") >> all_space
55
+ }
56
+
57
+ rule(:key) { match["^. \t\\]"].repeat(1) }
58
+ rule(:table_name) { key.as(:key) >> (str(".") >> key.as(:key)).repeat }
59
+
60
+ rule(:comment_line) { comment >> newline >> all_space }
61
+ rule(:comment) { str("#") >> match["^\n"].repeat }
62
+
63
+ rule(:space) { match[" \t"].repeat }
64
+ rule(:all_space) { match[" \t\r\n"].repeat }
65
+ rule(:newline) { str("\r").maybe >> str("\n") | str("\r") >> str("\n").maybe }
66
+
67
+ rule(:string) {
68
+ str('"') >> (
69
+ match["^\"\\\\"] |
70
+ (str("\\") >> match["0tnr\"\\\\"])
71
+ ).repeat.as(:string) >> str('"')
72
+ }
73
+
74
+ rule(:sign) { str("-") }
75
+ rule(:sign?) { sign.maybe }
76
+
77
+ rule(:integer) {
78
+ str("0") | sign? >>
79
+ (match["1-9"] >> (match["_"].maybe >> match["0-9"]).repeat)
80
+ }
81
+ rule(:float) {
82
+ sign? >>
83
+ (match["0-9"] >> (match["_"].maybe >> match["0-9"]).repeat) >> str(".") >>
84
+ (match["0-9"] >> (match["_"].maybe >> match["0-9"]).repeat)
85
+ }
86
+
87
+ rule(:boolean) { str("true").as(:true) | str("false").as(:false) }
88
+
89
+ rule(:date) {
90
+ match["0-9"].repeat(4,4) >> str("-") >>
91
+ match["0-9"].repeat(2,2) >> str("-") >>
92
+ match["0-9"].repeat(2,2)
93
+ }
94
+
95
+ rule(:time) {
96
+ match["0-9"].repeat(2,2) >> str(":") >>
97
+ match["0-9"].repeat(2,2) >> str(":") >>
98
+ match["0-9"].repeat(2,2)
99
+ }
100
+
101
+ rule(:datetime) { date >> str("T") >> time >> str("Z") }
102
+ end
103
+ end
data/lib/toml/table.rb ADDED
@@ -0,0 +1,10 @@
1
+ module TOML
2
+ class Table
3
+ # :name is array of strings
4
+ attr_reader :name
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+ end
9
+ class TableArray < Table; end
10
+ end
@@ -0,0 +1,115 @@
1
+ module TOML
2
+
3
+ class Transformer < ::Parslet::Transform
4
+ # Utility to properly handle escape sequences in parsed string.
5
+ def self.parse_string(val)
6
+ e = val.length
7
+ s = 0
8
+ o = []
9
+ while s < e
10
+ if val[s].chr == "\\"
11
+ s += 1
12
+ case val[s].chr
13
+ when "t"
14
+ o << "\t"
15
+ when "n"
16
+ o << "\n"
17
+ when "\\"
18
+ o << "\\"
19
+ when '"'
20
+ o << '"'
21
+ when "r"
22
+ o << "\r"
23
+ when "0"
24
+ o << "\0"
25
+ else
26
+ raise "Unexpected escape character: '\\#{val[s]}'"
27
+ end
28
+ else
29
+ o << val[s].chr
30
+ end
31
+ s += 1
32
+ end
33
+ o.join
34
+ end
35
+
36
+ # Clean up arrays
37
+ # rule(:array => subtree(:ar)) { ar.is_a?(Array) ? ar : [ar] }
38
+
39
+ # Empty file
40
+ rule('') {
41
+ nil
42
+ }
43
+
44
+ # Clean up simple value hashes
45
+ rule(:integer => simple(:i)) { i.to_i }
46
+ rule(:float => simple(:f)) { f.to_f }
47
+ rule(:string => simple(:s)) {
48
+ Transformer.parse_string(s.to_s)
49
+ }
50
+ rule(:string => sequence(:s)) {
51
+ raise "Unexpected string-sequence: #{s.inspect}" unless s.empty?
52
+ ""
53
+ }
54
+ rule(:datetime => simple(:d)) { DateTime.iso8601(d) }
55
+ rule(:true => simple(:b)) { true }
56
+ rule(:false => simple(:b)) { false }
57
+
58
+ rule(:key => simple(:k), :value => simple(:v)) { Key.new(k.to_s, v) }
59
+
60
+ # New array cleanup
61
+ # TODO: Make this more readable/understandable.
62
+ def self.visit_array(h)
63
+ if h.is_a? Hash
64
+ # If it's an {:array => ...} hash
65
+ a = h[:array]
66
+ if a.is_a? Array
67
+ # If the value is already an array
68
+ a = a.map {|v| visit_array(v) }
69
+ classes = a.map {|v|
70
+ # Grab the class, with a little exception for true and false since
71
+ # they're different classes (TrueClass and FalseClass).
72
+ (v == true || v == false) ? true : v.class
73
+ }
74
+ if classes.uniq.length != 1
75
+ raise "Conflicting types in array: " + \
76
+ classes.map(&:to_s).join(", ")
77
+ end
78
+ return a
79
+ else
80
+ # Turn the value into an array
81
+ return [visit_array(a)].compact
82
+ end
83
+ else
84
+ # Plain old non-hash value
85
+ return h
86
+ end
87
+ end
88
+ rule(:key => simple(:k), :value => subtree(:v)) {
89
+ Key.new(k.to_s, Transformer.visit_array(v))
90
+ }
91
+
92
+ # Make key hashes (inside key_groups) just be strings
93
+ rule(:key => simple(:k)) { k }
94
+
95
+ # Captures array-like key-groups
96
+ rule(:table => subtree(:kg)) {
97
+ Table.new(kg.map &:to_s)
98
+ }
99
+
100
+ # Then objectify the key_groups
101
+ rule(:table => simple(:kg)) {
102
+ Table.new([kg.to_s])
103
+ }
104
+
105
+ # Multi-part (a.b.c) table-arrays
106
+ rule(:table_array => subtree(:names)) {
107
+ TableArray.new(names.map &:to_s)
108
+ }
109
+
110
+ # Single name table-arrays
111
+ rule(:table_array => simple(:name)) {
112
+ TableArray.new([name.to_s])
113
+ }
114
+ end
115
+ end
@@ -0,0 +1,3 @@
1
+ module TOML
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toml_empty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy McAnally
8
+ - Dirk Gadsden
9
+ - Guillaume Virlet
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2021-05-13 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: parslet
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 1.8.0
22
+ - - "<"
23
+ - !ruby/object:Gem::Version
24
+ version: 3.0.0
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.8.0
32
+ - - "<"
33
+ - !ruby/object:Gem::Version
34
+ version: 3.0.0
35
+ - !ruby/object:Gem::Dependency
36
+ name: rake
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ description: Parse your TOML (allow empty group), seriously.
50
+ email: github@virlet.org
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files:
54
+ - README.md
55
+ - LICENSE
56
+ - CHANGELOG.md
57
+ files:
58
+ - CHANGELOG.md
59
+ - LICENSE
60
+ - README.md
61
+ - lib/toml.rb
62
+ - lib/toml/generator.rb
63
+ - lib/toml/key.rb
64
+ - lib/toml/monkey_patch.rb
65
+ - lib/toml/parser.rb
66
+ - lib/toml/parslet.rb
67
+ - lib/toml/table.rb
68
+ - lib/toml/transformer.rb
69
+ - lib/toml/version.rb
70
+ homepage: http://github.com/doc75/toml
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options:
76
+ - "--charset=UTF-8"
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubygems_version: 3.1.6
91
+ signing_key:
92
+ specification_version: 2
93
+ summary: Parse your TOML (allow empty group).
94
+ test_files: []