toml_empty 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +20 -0
- data/LICENSE +21 -0
- data/README.md +63 -0
- data/lib/toml.rb +25 -0
- data/lib/toml/generator.rb +29 -0
- data/lib/toml/key.rb +10 -0
- data/lib/toml/monkey_patch.rb +89 -0
- data/lib/toml/parser.rb +99 -0
- data/lib/toml/parslet.rb +103 -0
- data/lib/toml/table.rb +10 -0
- data/lib/toml/transformer.rb +115 -0
- data/lib/toml/version.rb +3 -0
- metadata +94 -0
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,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
|
data/lib/toml/parser.rb
ADDED
@@ -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
|
data/lib/toml/parslet.rb
ADDED
@@ -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,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
|
data/lib/toml/version.rb
ADDED
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: []
|