toml-rb-hs 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig ADDED
Binary file
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ toml-rb
2
+ =======
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/toml-rb.svg)](http://badge.fury.io/rb/toml-rb)
5
+ [![Build Status](https://travis-ci.org/emancu/toml-rb.svg)](https://travis-ci.org/emancu/toml-rb)
6
+ [![Code Climate](https://codeclimate.com/github/emancu/toml-rb/badges/gpa.svg)](https://codeclimate.com/github/emancu/toml-rb)
7
+ [![Dependency Status](https://gemnasium.com/emancu/toml-rb.svg)](https://gemnasium.com/emancu/toml-rb)
8
+
9
+ A [TomlRB](https://github.com/toml-lang/toml) parser using [Citrus](http://mjackson.github.io/citrus) library.
10
+
11
+ TomlRB specs supported: `0.4.0`
12
+
13
+ Installation
14
+ ------------
15
+
16
+ $ gem install toml-rb
17
+
18
+ Parser Usage
19
+ ------------
20
+
21
+ ```ruby
22
+ require 'toml-rb'
23
+
24
+ # From a file!
25
+ path = File.join(File.dirname(__FILE__), 'path', 'to', 'file')
26
+ TomlRB.load_file(path)
27
+
28
+ # From a stream!
29
+ stream = <<-EOS
30
+ title = "wow!"
31
+
32
+ [awesome]
33
+ you = true
34
+ others = false
35
+ EOS
36
+ TomlRB.parse(stream)
37
+ # => {"title"=>"wow!", "awesome"=>{"you"=>true, "others"=>false}}
38
+
39
+ # You want symbols as your keys? No problem!
40
+ TomlRB.load_file(path, symbolize_keys: true)
41
+ # Works the same for TomlRB.parse
42
+ ```
43
+
44
+ Dumper Usage
45
+ ------------
46
+
47
+ ```ruby
48
+ require 'toml-rb'
49
+
50
+ # Simple example
51
+ TomlRB.dump( simple: true)
52
+ # => "simple = true\n"
53
+
54
+
55
+ # Complex example
56
+ hash = {
57
+ "title"=>"wow!",
58
+ "awesome"=> {
59
+ "you"=>true,
60
+ "others"=>false
61
+ }
62
+ }
63
+
64
+ TomlRB.dump(hash)
65
+ # => "title = \"wow!\"\n[awesome]\nothers = false\nyou = true\n"
66
+ ```
67
+
68
+ Contributing
69
+ ------------
70
+
71
+ 1. Fork it
72
+ 2. Bundle it `$ dep install` (install [dep](https://github.com/cyx/dep) if you don't have it)
73
+ 3. Create your feature branch `git checkout -b my-new-feature`
74
+ 4. Add tests and commit your changes `git commit -am 'Add some feature'`
75
+ 5. Run tests `$ rake`
76
+ 6. Push the branch `git push origin my-new-feature`
77
+ 7. Create new Pull Request
78
+
79
+ License
80
+ -------
81
+
82
+ MIT License
83
+
84
+ Permission is hereby granted, free of charge, to any person obtaining
85
+ a copy of this software and associated documentation files (the
86
+ "Software"), to deal in the Software without restriction, including
87
+ without limitation the rights to use, copy, modify, merge, publish,
88
+ distribute, sublicense, and/or sell copies of the Software, and to
89
+ permit persons to whom the Software is furnished to do so, subject to
90
+ the following conditions:
91
+
92
+ The above copyright notice and this permission notice shall be
93
+ included in all copies or substantial portions of the Software.
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
96
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
97
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
98
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
99
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
100
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
101
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.pattern = 'test/*_test.rb'
5
+ end
6
+ task default: :test
data/lib/toml-rb.rb ADDED
@@ -0,0 +1,106 @@
1
+ require 'citrus'
2
+
3
+ unless defined? require_relative
4
+ def require_relative(path)
5
+ require path
6
+ end
7
+ end
8
+
9
+ require_relative "toml-rb/errors"
10
+ require_relative "toml-rb/array"
11
+ require_relative "toml-rb/string"
12
+ require_relative "toml-rb/table_array"
13
+ require_relative "toml-rb/inline_table"
14
+ require_relative "toml-rb/keyvalue"
15
+ require_relative "toml-rb/keygroup"
16
+ require_relative "toml-rb/parser"
17
+ require_relative "toml-rb/dumper"
18
+
19
+ ROOT = File.dirname(File.expand_path(__FILE__))
20
+ Citrus.load "#{ROOT}/toml-rb/grammars/helper.citrus"
21
+ Citrus.load "#{ROOT}/toml-rb/grammars/primitive.citrus"
22
+ Citrus.load "#{ROOT}/toml-rb/grammars/array.citrus"
23
+ Citrus.load "#{ROOT}/toml-rb/grammars/document.citrus"
24
+
25
+ module TomlRB
26
+ # Public: Returns a hash from *TomlRB* content.
27
+ #
28
+ # content - TomlRB string to be parsed.
29
+ # options - The Hash options used to refine the parser (default: {}):
30
+ # :symbolize_keys - true|false (optional).
31
+ #
32
+ #
33
+ # Examples
34
+ #
35
+ # TomlRB.parse('[group]')
36
+ # # => {"group"=>{}}
37
+ #
38
+ # TomlRB.parse('title = "TomlRB parser"')
39
+ # # => {"title"=>"TomlRB parser"}
40
+ #
41
+ # TomlRB.parse('[group]', symbolize_keys: true)
42
+ # # => {group: {}}
43
+ #
44
+ # TomlRB.parse('title = "TomlRB parser"', symbolize_keys: true)
45
+ # # => {title: "TomlRB parser"}
46
+ #
47
+ #
48
+ # Returns a Ruby hash representation of the content according to TomlRB spec.
49
+ # Raises ValueOverwriteError if a key is overwritten.
50
+ # Raises ParseError if the content has invalid TomlRB.
51
+ def self.parse(content, options = {})
52
+ Parser.new(content, options).hash
53
+ end
54
+
55
+ # Public: Returns a hash from a *TomlRB* file.
56
+ #
57
+ # path - TomlRB File path
58
+ # options - The Hash options used to refine the parser (default: {}):
59
+ # :symbolize_keys - true|false (optional).
60
+ #
61
+ #
62
+ # Examples
63
+ #
64
+ # TomlRB.load_file('/tmp/simple.toml')
65
+ # # => {"group"=>{}}
66
+ #
67
+ # TomlRB.load_file('/tmp/simple.toml', symbolize_keys: true)
68
+ # # => {group: {}}
69
+ #
70
+ #
71
+ # Returns a Ruby hash representation of the content.
72
+ # Raises ValueOverwriteError if a key is overwritten.
73
+ # Raises ParseError if the content has invalid TomlRB.
74
+ # Raises Errno::ENOENT if the file cannot be found.
75
+ # Raises Errno::EACCES if the file cannot be accessed.
76
+ def self.load_file(path, options = {})
77
+ TomlRB.parse(File.read(path), options)
78
+ end
79
+
80
+ # Public: Returns a *TomlRB* string from a Ruby Hash.
81
+ #
82
+ # hash - Ruby Hash to be dumped into *TomlRB*
83
+ #
84
+ #
85
+ # Examples
86
+ #
87
+ # TomlRB.dump(title: 'TomlRB dump')
88
+ # # => "simple = true\n"
89
+ #
90
+ # hash = {
91
+ # "title"=>"wow!",
92
+ # "awesome"=> {
93
+ # "you"=>true,
94
+ # "others"=>false
95
+ # }
96
+ # }
97
+ #
98
+ # TomlRB.dump(hash)
99
+ # # => "title = \"wow!\"\n[awesome]\nothers = false\nyou = true\n"
100
+ #
101
+ #
102
+ # Returns a TomlRB string representing the hash.
103
+ def self.dump(hash)
104
+ Dumper.new(hash).toml_str
105
+ end
106
+ end
@@ -0,0 +1,14 @@
1
+ module TomlRB
2
+ module ArrayParser
3
+ def value
4
+ elements = captures[:elements].first
5
+ return [] unless elements
6
+
7
+ if elements.captures.key? :string
8
+ elements.captures[:string].map(&:value)
9
+ else
10
+ eval(to_str)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,103 @@
1
+ module TomlRB
2
+ class Dumper
3
+ attr_reader :toml_str
4
+
5
+ def initialize(hash)
6
+ @toml_str = ''
7
+
8
+ visit(hash, [])
9
+ end
10
+
11
+ private
12
+
13
+ def visit(hash, prefix, extra_brackets = false)
14
+ simple_pairs, nested_pairs, table_array_pairs = sort_pairs hash
15
+
16
+ if prefix.any? && (simple_pairs.any? || hash.empty?)
17
+ print_prefix prefix, extra_brackets
18
+ end
19
+
20
+ dump_pairs simple_pairs, nested_pairs, table_array_pairs, prefix
21
+ end
22
+
23
+ def sort_pairs(hash)
24
+ nested_pairs = []
25
+ simple_pairs = []
26
+ table_array_pairs = []
27
+
28
+ hash.keys.sort.each do |key|
29
+ val = hash[key]
30
+ element = [key, val]
31
+
32
+ if val.is_a? Hash
33
+ nested_pairs << element
34
+ elsif val.is_a?(Array) && val.first.is_a?(Hash)
35
+ table_array_pairs << element
36
+ else
37
+ simple_pairs << element
38
+ end
39
+ end
40
+
41
+ [simple_pairs, nested_pairs, table_array_pairs]
42
+ end
43
+
44
+ def dump_pairs(simple, nested, table_array, prefix = [])
45
+ # First add simple pairs, under the prefix
46
+ dump_simple_pairs simple
47
+ dump_nested_pairs nested, prefix
48
+ dump_table_array_pairs table_array, prefix
49
+ end
50
+
51
+ def dump_simple_pairs(simple_pairs)
52
+ simple_pairs.each do |key, val|
53
+ key = quote_key(key) unless bare_key? key
54
+ @toml_str << "#{key} = #{to_toml(val)}\n"
55
+ end
56
+ end
57
+
58
+ def dump_nested_pairs(nested_pairs, prefix)
59
+ nested_pairs.each do |key, val|
60
+ key = quote_key(key) unless bare_key? key
61
+
62
+ visit val, prefix + [key], false
63
+ end
64
+ end
65
+
66
+ def dump_table_array_pairs(table_array_pairs, prefix)
67
+ table_array_pairs.each do |key, val|
68
+ key = quote_key(key) unless bare_key? key
69
+ aux_prefix = prefix + [key]
70
+
71
+ val.each do |child|
72
+ print_prefix aux_prefix, true
73
+ args = sort_pairs(child) << aux_prefix
74
+
75
+ dump_pairs(*args)
76
+ end
77
+ end
78
+ end
79
+
80
+ def print_prefix(prefix, extra_brackets = false)
81
+ new_prefix = prefix.join('.')
82
+ new_prefix = '[' + new_prefix + ']' if extra_brackets
83
+
84
+ @toml_str += "[" + new_prefix + "]\n"
85
+ end
86
+
87
+ def to_toml(obj)
88
+ if obj.is_a? Time
89
+ obj.strftime('%Y-%m-%dT%H:%M:%SZ')
90
+ else
91
+ obj.inspect
92
+ end
93
+ end
94
+
95
+ def bare_key?(key)
96
+ !!key.to_s.match(/^[a-zA-Z0-9_-]*$/)
97
+ end
98
+
99
+ def quote_key(key)
100
+ '"' + key.gsub('"', '\\"') + '"'
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,17 @@
1
+ module TomlRB
2
+ # Parent class for all TomlRB errors
3
+ Error = Class.new(StandardError)
4
+
5
+ # Error related to parsing.
6
+ ParseError = Class.new(Error)
7
+
8
+ # Overwrite error
9
+ class ValueOverwriteError < Error
10
+ attr_accessor :key
11
+
12
+ def initialize(key)
13
+ @key = key
14
+ super "Key #{key.inspect} is defined more than once"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ grammar TomlRB::Arrays
2
+ include TomlRB::Primitive
3
+
4
+ rule array
5
+ ("[" array_comments (elements)? space ","? array_comments "]" indent?) <TomlRB::ArrayParser>
6
+ end
7
+
8
+ rule array_comments
9
+ (indent? comment* indent?)
10
+ end
11
+
12
+ rule elements
13
+ float_array | string_array | array_array | integer_array | datetime_array | bool_array
14
+ end
15
+
16
+ rule float_array
17
+ ((exponent | float) (space "," array_comments (exponent | float))*)
18
+ end
19
+
20
+ rule string_array
21
+ (string (space "," array_comments string)*)
22
+ end
23
+
24
+ rule array_array
25
+ (array (space "," array_comments array)*)
26
+ end
27
+
28
+ rule integer_array
29
+ (integer (space "," array_comments integer)*)
30
+ end
31
+
32
+ rule datetime_array
33
+ (datetime (space "," array_comments datetime)*)
34
+ end
35
+
36
+ rule bool_array
37
+ (bool (space "," array_comments bool)*)
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ grammar TomlRB::Document
2
+ include TomlRB::Primitive
3
+ include TomlRB::Arrays
4
+
5
+ rule document
6
+ (comment | table_array | keygroup | keyvalue | line_break)*
7
+ end
8
+
9
+ rule table_array
10
+ (space? '[[' stripped_key ("." stripped_key)* ']]' comment?) <TomlRB::TableArrayParser>
11
+ end
12
+
13
+ rule keygroup
14
+ (space? '[' stripped_key ("." stripped_key)* ']' comment?) <TomlRB::KeygroupParser>
15
+ end
16
+
17
+ rule keyvalue
18
+ (stripped_key '=' space? v:(toml_values) comment?) <TomlRB::KeyvalueParser>
19
+ end
20
+
21
+ rule inline_table
22
+ (space? '{' (keyvalue (',' keyvalue)*)? space? '}' ) <TomlRB::InlineTableParser>
23
+ end
24
+
25
+ rule inline_table_array
26
+ ("[" array_comments inline_table_array_elements space ","? array_comments "]" indent?) <TomlRB::InlineTableArrayParser>
27
+ end
28
+
29
+ rule inline_table_array_elements
30
+ (inline_table (space "," array_comments inline_table)*)
31
+ end
32
+
33
+ rule toml_values
34
+ primitive | inline_table | array | inline_table_array
35
+ end
36
+
37
+ rule stripped_key
38
+ (space? key space?) { captures[:key].first.value }
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ grammar TomlRB::Helper
2
+ rule comment
3
+ (space? "#" (~line_break)* line_break?) { nil }
4
+ end
5
+
6
+ rule space
7
+ [ \t]*
8
+ end
9
+
10
+ rule indent
11
+ [ \t\r\n]*
12
+ end
13
+
14
+ rule line_break
15
+ (space? "\n" | space? "\r\n") { nil }
16
+ end
17
+ end