shale 0.4.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +34 -0
- data/LICENSE.txt +1 -1
- data/README.md +449 -40
- data/exe/shaleb +30 -6
- data/lib/shale/adapter/json.rb +3 -3
- data/lib/shale/adapter/nokogiri/document.rb +97 -0
- data/lib/shale/adapter/nokogiri/node.rb +100 -0
- data/lib/shale/adapter/nokogiri.rb +17 -156
- data/lib/shale/adapter/ox/document.rb +90 -0
- data/lib/shale/adapter/ox/node.rb +97 -0
- data/lib/shale/adapter/ox.rb +14 -138
- data/lib/shale/adapter/rexml/document.rb +98 -0
- data/lib/shale/adapter/rexml/node.rb +99 -0
- data/lib/shale/adapter/rexml.rb +14 -154
- data/lib/shale/adapter/toml_rb.rb +34 -0
- data/lib/shale/error.rb +57 -2
- data/lib/shale/mapper.rb +61 -9
- data/lib/shale/mapping/descriptor/dict.rb +12 -1
- data/lib/shale/mapping/descriptor/xml.rb +12 -2
- data/lib/shale/mapping/dict.rb +26 -2
- data/lib/shale/mapping/xml.rb +52 -6
- data/lib/shale/schema/{json_compiler → compiler}/boolean.rb +1 -1
- data/lib/shale/schema/{json_compiler/object.rb → compiler/complex.rb} +11 -8
- data/lib/shale/schema/{json_compiler → compiler}/date.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/float.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/integer.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/property.rb +6 -6
- data/lib/shale/schema/{json_compiler → compiler}/string.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/time.rb +1 -1
- data/lib/shale/schema/compiler/value.rb +21 -0
- data/lib/shale/schema/compiler/xml_complex.rb +50 -0
- data/lib/shale/schema/compiler/xml_property.rb +73 -0
- data/lib/shale/schema/json_compiler.rb +32 -34
- data/lib/shale/schema/json_generator.rb +4 -6
- data/lib/shale/schema/xml_compiler.rb +919 -0
- data/lib/shale/schema/xml_generator/import.rb +2 -2
- data/lib/shale/schema/xml_generator.rb +11 -13
- data/lib/shale/schema.rb +16 -0
- data/lib/shale/type/complex.rb +763 -0
- data/lib/shale/type/value.rb +38 -9
- data/lib/shale/utils.rb +42 -7
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +22 -19
- data/shale.gemspec +3 -3
- metadata +26 -17
- data/lib/shale/schema/json_compiler/utils.rb +0 -52
- data/lib/shale/schema/json_compiler/value.rb +0 -13
- data/lib/shale/type/composite.rb +0 -331
data/lib/shale/adapter/ox.rb
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'ox'
|
4
4
|
|
5
|
+
require_relative '../error'
|
6
|
+
require_relative 'ox/document'
|
7
|
+
require_relative 'ox/node'
|
8
|
+
|
5
9
|
module Shale
|
6
10
|
module Adapter
|
7
11
|
# Ox adapter
|
@@ -12,29 +16,34 @@ module Shale
|
|
12
16
|
#
|
13
17
|
# @param [String] xml XML document
|
14
18
|
#
|
15
|
-
# @
|
19
|
+
# @raise [ParseError] when XML document has errors
|
20
|
+
#
|
21
|
+
# @return [Shale::Adapter::Ox::Node]
|
16
22
|
#
|
17
23
|
# @api private
|
18
24
|
def self.load(xml)
|
19
25
|
Node.new(::Ox.parse(xml))
|
26
|
+
rescue ::Ox::ParseError => e
|
27
|
+
raise ParseError, "Document is invalid: #{e.message}"
|
20
28
|
end
|
21
29
|
|
22
30
|
# Serialize Ox document into XML
|
23
31
|
#
|
24
32
|
# @param [::Ox::Document, ::Ox::Element] doc Ox document
|
25
|
-
# @param [
|
33
|
+
# @param [true, false] pretty
|
34
|
+
# @param [true, false] declaration
|
26
35
|
#
|
27
36
|
# @return [String]
|
28
37
|
#
|
29
38
|
# @api private
|
30
|
-
def self.dump(doc,
|
39
|
+
def self.dump(doc, pretty: false, declaration: false)
|
31
40
|
opts = { indent: -1, with_xml: false }
|
32
41
|
|
33
|
-
if
|
42
|
+
if pretty
|
34
43
|
opts[:indent] = 2
|
35
44
|
end
|
36
45
|
|
37
|
-
if
|
46
|
+
if declaration
|
38
47
|
doc[:version] = '1.0'
|
39
48
|
opts[:with_xml] = true
|
40
49
|
end
|
@@ -48,139 +57,6 @@ module Shale
|
|
48
57
|
def self.create_document
|
49
58
|
Document.new
|
50
59
|
end
|
51
|
-
|
52
|
-
# Wrapper around Ox API
|
53
|
-
#
|
54
|
-
# @api private
|
55
|
-
class Document
|
56
|
-
# Return Ox document
|
57
|
-
#
|
58
|
-
# @return [::Ox::Document]
|
59
|
-
#
|
60
|
-
# @api private
|
61
|
-
attr_reader :doc
|
62
|
-
|
63
|
-
# Initialize object
|
64
|
-
#
|
65
|
-
# @api private
|
66
|
-
def initialize
|
67
|
-
@doc = ::Ox::Document.new
|
68
|
-
end
|
69
|
-
|
70
|
-
# Create Ox element
|
71
|
-
#
|
72
|
-
# @param [String] name Name of the XML element
|
73
|
-
#
|
74
|
-
# @return [::Ox::Element]
|
75
|
-
#
|
76
|
-
# @api private
|
77
|
-
def create_element(name)
|
78
|
-
::Ox::Element.new(name)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Add XML namespace to document
|
82
|
-
#
|
83
|
-
# Ox doesn't support XML namespaces so this method does nothing.
|
84
|
-
#
|
85
|
-
# @param [String] prefix
|
86
|
-
# @param [String] namespace
|
87
|
-
#
|
88
|
-
# @api private
|
89
|
-
def add_namespace(prefix, namespace)
|
90
|
-
# :noop:
|
91
|
-
end
|
92
|
-
|
93
|
-
# Add attribute to Ox element
|
94
|
-
#
|
95
|
-
# @param [::Ox::Element] element Ox element
|
96
|
-
# @param [String] name Name of the XML attribute
|
97
|
-
# @param [String] value Value of the XML attribute
|
98
|
-
#
|
99
|
-
# @api private
|
100
|
-
def add_attribute(element, name, value)
|
101
|
-
element[name] = value
|
102
|
-
end
|
103
|
-
|
104
|
-
# Add child element to Ox element
|
105
|
-
#
|
106
|
-
# @param [::Ox::Element] element Ox parent element
|
107
|
-
# @param [::Ox::Element] child Ox child element
|
108
|
-
#
|
109
|
-
# @api private
|
110
|
-
def add_element(element, child)
|
111
|
-
element << child
|
112
|
-
end
|
113
|
-
|
114
|
-
# Add text node to Ox element
|
115
|
-
#
|
116
|
-
# @param [::Ox::Element] element Ox element
|
117
|
-
# @param [String] text Text to add
|
118
|
-
#
|
119
|
-
# @api private
|
120
|
-
def add_text(element, text)
|
121
|
-
element << text
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Wrapper around Ox::Element API
|
126
|
-
#
|
127
|
-
# @api private
|
128
|
-
class Node
|
129
|
-
# Initialize object with Ox element
|
130
|
-
#
|
131
|
-
# @param [::Ox::Element] node Ox element
|
132
|
-
#
|
133
|
-
# @api private
|
134
|
-
def initialize(node)
|
135
|
-
@node = node
|
136
|
-
end
|
137
|
-
|
138
|
-
# Return name of the node in the format of
|
139
|
-
# prefix:name when the node is namespaced or just name when it's not
|
140
|
-
#
|
141
|
-
# @return [String]
|
142
|
-
#
|
143
|
-
# @example without namespace
|
144
|
-
# node.name # => Bar
|
145
|
-
#
|
146
|
-
# @example with namespace
|
147
|
-
# node.name # => foo:Bar
|
148
|
-
#
|
149
|
-
# @api private
|
150
|
-
def name
|
151
|
-
@node.name
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return all attributes associated with the node
|
155
|
-
#
|
156
|
-
# @return [Hash]
|
157
|
-
#
|
158
|
-
# @api private
|
159
|
-
def attributes
|
160
|
-
@node.attributes
|
161
|
-
end
|
162
|
-
|
163
|
-
# Return node's element children
|
164
|
-
#
|
165
|
-
# @return [Array<Shale::Adapter::Ox::Node>]
|
166
|
-
#
|
167
|
-
# @api private
|
168
|
-
def children
|
169
|
-
@node
|
170
|
-
.nodes
|
171
|
-
.filter { |e| e.is_a?(::Ox::Element) }
|
172
|
-
.map { |e| self.class.new(e) }
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return first text child of a node
|
176
|
-
#
|
177
|
-
# @return [String]
|
178
|
-
#
|
179
|
-
# @api private
|
180
|
-
def text
|
181
|
-
@node.text
|
182
|
-
end
|
183
|
-
end
|
184
60
|
end
|
185
61
|
end
|
186
62
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Adapter
|
5
|
+
module REXML
|
6
|
+
# Wrapper around REXML API
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Document
|
10
|
+
# Initialize object
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
def initialize
|
14
|
+
context = { attribute_quote: :quote, prologue_quote: :quote }
|
15
|
+
@doc = ::REXML::Document.new(nil, context)
|
16
|
+
@namespaces = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return REXML document
|
20
|
+
#
|
21
|
+
# @return [::REXML::Document]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
def doc
|
25
|
+
if @doc.root
|
26
|
+
@namespaces.each do |prefix, namespace|
|
27
|
+
@doc.root.add_namespace(prefix, namespace)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@doc
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create REXML element
|
35
|
+
#
|
36
|
+
# @param [String] name Name of the XML element
|
37
|
+
#
|
38
|
+
# @return [::REXML::Element]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def create_element(name)
|
42
|
+
::REXML::Element.new(name, nil, attribute_quote: :quote)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Create CDATA node and add it to parent
|
46
|
+
#
|
47
|
+
# @param [String] text
|
48
|
+
# @param [::REXML::Element] parent
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
def create_cdata(text, parent)
|
52
|
+
::REXML::CData.new(text, true, parent)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add XML namespace to document
|
56
|
+
#
|
57
|
+
# @param [String] prefix
|
58
|
+
# @param [String] namespace
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def add_namespace(prefix, namespace)
|
62
|
+
@namespaces[prefix] = namespace if prefix && namespace
|
63
|
+
end
|
64
|
+
|
65
|
+
# Add attribute to REXML element
|
66
|
+
#
|
67
|
+
# @param [::REXML::Element] element REXML element
|
68
|
+
# @param [String] name Name of the XML attribute
|
69
|
+
# @param [String] value Value of the XML attribute
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def add_attribute(element, name, value)
|
73
|
+
element.add_attribute(name, value || '')
|
74
|
+
end
|
75
|
+
|
76
|
+
# Add child element to REXML element
|
77
|
+
#
|
78
|
+
# @param [::REXML::Element] element REXML parent element
|
79
|
+
# @param [::REXML::Element] child REXML child element
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def add_element(element, child)
|
83
|
+
element.add_element(child)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Add text node to REXML element
|
87
|
+
#
|
88
|
+
# @param [::REXML::Element] element REXML element
|
89
|
+
# @param [String] text Text to add
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
def add_text(element, text)
|
93
|
+
element.add_text(text)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../utils'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Adapter
|
7
|
+
module REXML
|
8
|
+
# Wrapper around REXML::Element API
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Node
|
12
|
+
# Initialize object with REXML element
|
13
|
+
#
|
14
|
+
# @param [::REXML::Element] node REXML element
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
def initialize(node)
|
18
|
+
@node = node
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return namespaces defined on document
|
22
|
+
#
|
23
|
+
# @return [Hash<String, String>]
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# node.namespaces # => { 'foo' => 'http://foo.com', 'bar' => 'http://bar.com' }
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
def namespaces
|
30
|
+
@node.namespaces
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return name of the node in the format of
|
34
|
+
# namespace:name when the node is namespaced or just name when it's not
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
#
|
38
|
+
# @example without namespace
|
39
|
+
# node.name # => Bar
|
40
|
+
#
|
41
|
+
# @example with namespace
|
42
|
+
# node.name # => http://foo:Bar
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
def name
|
46
|
+
[Utils.presence(@node.namespace), @node.name].compact.join(':')
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return all attributes associated with the node
|
50
|
+
#
|
51
|
+
# @return [Hash]
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
def attributes
|
55
|
+
attributes = @node.attributes.values.map do |attribute|
|
56
|
+
attribute.is_a?(Hash) ? attribute.values : attribute
|
57
|
+
end.flatten
|
58
|
+
|
59
|
+
attributes.each_with_object({}) do |attribute, hash|
|
60
|
+
name = [Utils.presence(attribute.namespace), attribute.name].compact.join(':')
|
61
|
+
hash[name] = attribute.value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return node's parent
|
66
|
+
#
|
67
|
+
# @return [Shale::Adapter::REXML::Node, nil]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
def parent
|
71
|
+
if @node.parent && @node.parent.name != ''
|
72
|
+
self.class.new(@node.parent)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return node's element children
|
77
|
+
#
|
78
|
+
# @return [Array<Shale::Adapter::REXML::Node>]
|
79
|
+
#
|
80
|
+
# @api private
|
81
|
+
def children
|
82
|
+
@node
|
83
|
+
.children
|
84
|
+
.filter { |e| e.node_type == :element }
|
85
|
+
.map { |e| self.class.new(e) }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return first text child of a node
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
#
|
92
|
+
# @api private
|
93
|
+
def text
|
94
|
+
@node.text
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/shale/adapter/rexml.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rexml/document'
|
4
|
-
|
4
|
+
|
5
|
+
require_relative '../error'
|
6
|
+
require_relative 'rexml/document'
|
7
|
+
require_relative 'rexml/node'
|
5
8
|
|
6
9
|
module Shale
|
7
10
|
module Adapter
|
@@ -13,30 +16,35 @@ module Shale
|
|
13
16
|
#
|
14
17
|
# @param [String] xml XML document
|
15
18
|
#
|
16
|
-
# @
|
19
|
+
# @raise [ParseError] when XML document has errors
|
20
|
+
#
|
21
|
+
# @return [Shale::Adapter::REXML::Node]
|
17
22
|
#
|
18
23
|
# @api private
|
19
24
|
def self.load(xml)
|
20
25
|
doc = ::REXML::Document.new(xml, ignore_whitespace_nodes: :all)
|
21
26
|
Node.new(doc.root)
|
27
|
+
rescue ::REXML::ParseException => e
|
28
|
+
raise ParseError, "Document is invalid: #{e.message}"
|
22
29
|
end
|
23
30
|
|
24
31
|
# Serialize REXML document into XML
|
25
32
|
#
|
26
33
|
# @param [::REXML::Document] doc REXML document
|
27
|
-
# @param [
|
34
|
+
# @param [true, false] pretty
|
35
|
+
# @param [true, false] declaration
|
28
36
|
#
|
29
37
|
# @return [String]
|
30
38
|
#
|
31
39
|
# @api private
|
32
|
-
def self.dump(doc,
|
33
|
-
if
|
40
|
+
def self.dump(doc, pretty: false, declaration: false)
|
41
|
+
if declaration
|
34
42
|
doc.add(::REXML::XMLDecl.new)
|
35
43
|
end
|
36
44
|
|
37
45
|
io = StringIO.new
|
38
46
|
|
39
|
-
if
|
47
|
+
if pretty
|
40
48
|
formatter = ::REXML::Formatters::Pretty.new
|
41
49
|
formatter.compact = true
|
42
50
|
else
|
@@ -53,154 +61,6 @@ module Shale
|
|
53
61
|
def self.create_document
|
54
62
|
Document.new
|
55
63
|
end
|
56
|
-
|
57
|
-
# Wrapper around REXML API
|
58
|
-
#
|
59
|
-
# @api private
|
60
|
-
class Document
|
61
|
-
# Initialize object
|
62
|
-
#
|
63
|
-
# @api private
|
64
|
-
def initialize
|
65
|
-
context = { attribute_quote: :quote, prologue_quote: :quote }
|
66
|
-
@doc = ::REXML::Document.new(nil, context)
|
67
|
-
@namespaces = {}
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return REXML document
|
71
|
-
#
|
72
|
-
# @return [::REXML::Document]
|
73
|
-
#
|
74
|
-
# @api private
|
75
|
-
def doc
|
76
|
-
if @doc.root
|
77
|
-
@namespaces.each do |prefix, namespace|
|
78
|
-
@doc.root.add_namespace(prefix, namespace)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
@doc
|
83
|
-
end
|
84
|
-
|
85
|
-
# Create REXML element
|
86
|
-
#
|
87
|
-
# @param [String] name Name of the XML element
|
88
|
-
#
|
89
|
-
# @return [::REXML::Element]
|
90
|
-
#
|
91
|
-
# @api private
|
92
|
-
def create_element(name)
|
93
|
-
::REXML::Element.new(name, nil, attribute_quote: :quote)
|
94
|
-
end
|
95
|
-
|
96
|
-
# Add XML namespace to document
|
97
|
-
#
|
98
|
-
# @param [String] prefix
|
99
|
-
# @param [String] namespace
|
100
|
-
#
|
101
|
-
# @api private
|
102
|
-
def add_namespace(prefix, namespace)
|
103
|
-
@namespaces[prefix] = namespace if prefix && namespace
|
104
|
-
end
|
105
|
-
|
106
|
-
# Add attribute to REXML element
|
107
|
-
#
|
108
|
-
# @param [::REXML::Element] element REXML element
|
109
|
-
# @param [String] name Name of the XML attribute
|
110
|
-
# @param [String] value Value of the XML attribute
|
111
|
-
#
|
112
|
-
# @api private
|
113
|
-
def add_attribute(element, name, value)
|
114
|
-
element.add_attribute(name, value)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Add child element to REXML element
|
118
|
-
#
|
119
|
-
# @param [::REXML::Element] element REXML parent element
|
120
|
-
# @param [::REXML::Element] child REXML child element
|
121
|
-
#
|
122
|
-
# @api private
|
123
|
-
def add_element(element, child)
|
124
|
-
element.add_element(child)
|
125
|
-
end
|
126
|
-
|
127
|
-
# Add text node to REXML element
|
128
|
-
#
|
129
|
-
# @param [::REXML::Element] element REXML element
|
130
|
-
# @param [String] text Text to add
|
131
|
-
#
|
132
|
-
# @api private
|
133
|
-
def add_text(element, text)
|
134
|
-
element.add_text(text)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# Wrapper around REXML::Element API
|
139
|
-
#
|
140
|
-
# @api private
|
141
|
-
class Node
|
142
|
-
# Initialize object with REXML element
|
143
|
-
#
|
144
|
-
# @param [::REXML::Element] node REXML element
|
145
|
-
#
|
146
|
-
# @api private
|
147
|
-
def initialize(node)
|
148
|
-
@node = node
|
149
|
-
end
|
150
|
-
|
151
|
-
# Return name of the node in the format of
|
152
|
-
# namespace:name when the node is namespaced or just name when it's not
|
153
|
-
#
|
154
|
-
# @return [String]
|
155
|
-
#
|
156
|
-
# @example without namespace
|
157
|
-
# node.name # => Bar
|
158
|
-
#
|
159
|
-
# @example with namespace
|
160
|
-
# node.name # => http://foo:Bar
|
161
|
-
#
|
162
|
-
# @api private
|
163
|
-
def name
|
164
|
-
[Utils.presence(@node.namespace), @node.name].compact.join(':')
|
165
|
-
end
|
166
|
-
|
167
|
-
# Return all attributes associated with the node
|
168
|
-
#
|
169
|
-
# @return [Hash]
|
170
|
-
#
|
171
|
-
# @api private
|
172
|
-
def attributes
|
173
|
-
attributes = @node.attributes.values.map do |attribute|
|
174
|
-
attribute.is_a?(Hash) ? attribute.values : attribute
|
175
|
-
end.flatten
|
176
|
-
|
177
|
-
attributes.each_with_object({}) do |attribute, hash|
|
178
|
-
name = [Utils.presence(attribute.namespace), attribute.name].compact.join(':')
|
179
|
-
hash[name] = attribute.value
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# Return node's element children
|
184
|
-
#
|
185
|
-
# @return [Array<Shale::Adapter::REXML::Node>]
|
186
|
-
#
|
187
|
-
# @api private
|
188
|
-
def children
|
189
|
-
@node
|
190
|
-
.children
|
191
|
-
.filter { |e| e.node_type == :element }
|
192
|
-
.map { |e| self.class.new(e) }
|
193
|
-
end
|
194
|
-
|
195
|
-
# Return first text child of a node
|
196
|
-
#
|
197
|
-
# @return [String]
|
198
|
-
#
|
199
|
-
# @api private
|
200
|
-
def text
|
201
|
-
@node.text
|
202
|
-
end
|
203
|
-
end
|
204
64
|
end
|
205
65
|
end
|
206
66
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'toml-rb'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Adapter
|
7
|
+
# TOML adapter
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
class TomlRB
|
11
|
+
# Parse TOML into Hash
|
12
|
+
#
|
13
|
+
# @param [String] toml TOML document
|
14
|
+
#
|
15
|
+
# @return [Hash]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
def self.load(toml)
|
19
|
+
::TomlRB.parse(toml)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Serialize Hash into TOML
|
23
|
+
#
|
24
|
+
# @param [Hash] obj Hash object
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
def self.dump(obj)
|
30
|
+
::TomlRB.dump(obj)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/shale/error.rb
CHANGED
@@ -1,6 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Shale
|
4
|
+
# Error message displayed when TOML adapter is not set
|
5
|
+
# @api private
|
6
|
+
TOML_ADAPTER_NOT_SET_MESSAGE = <<~MSG
|
7
|
+
TOML Adapter is not set.
|
8
|
+
To use Shale with TOML documents you have to install parser and set adapter.
|
9
|
+
|
10
|
+
# To use Tomlib:
|
11
|
+
# Make sure tomlib is installed eg. execute: gem install tomlib
|
12
|
+
Shale.toml_adapter = Tomlib
|
13
|
+
|
14
|
+
# To use toml-rb:
|
15
|
+
# Make sure toml-rb is installed eg. execute: gem install toml-rb
|
16
|
+
require 'shale/adapter/toml_rb'
|
17
|
+
Shale.toml_adapter = Shale::Adapter::TomlRB
|
18
|
+
MSG
|
19
|
+
|
20
|
+
# Error message displayed when XML adapter is not set
|
21
|
+
# @api private
|
22
|
+
XML_ADAPTER_NOT_SET_MESSAGE = <<~MSG
|
23
|
+
XML Adapter is not set.
|
24
|
+
To use Shale with XML documents you have to install parser and set adapter.
|
25
|
+
|
26
|
+
# To use REXML:
|
27
|
+
require 'shale/adapter/rexml'
|
28
|
+
Shale.xml_adapter = Shale::Adapter::REXML
|
29
|
+
|
30
|
+
# To use Nokogiri:
|
31
|
+
# Make sure Nokogiri is installed eg. execute: gem install nokogiri
|
32
|
+
require 'shale/adapter/nokogiri'
|
33
|
+
Shale.xml_adapter = Shale::Adapter::Nokogiri
|
34
|
+
|
35
|
+
# To use OX:
|
36
|
+
# Make sure Ox is installed eg. execute: gem install ox
|
37
|
+
require 'shale/adapter/ox'
|
38
|
+
Shale.xml_adapter = Shale::Adapter::Ox
|
39
|
+
MSG
|
40
|
+
|
4
41
|
# Error for assigning value to not existing attribute
|
5
42
|
#
|
6
43
|
# @api private
|
@@ -31,6 +68,12 @@ module Shale
|
|
31
68
|
end
|
32
69
|
end
|
33
70
|
|
71
|
+
# Error for passing incorrect model type
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
class IncorrectModelError < StandardError
|
75
|
+
end
|
76
|
+
|
34
77
|
# Error for passing incorrect arguments to map functions
|
35
78
|
#
|
36
79
|
# @api private
|
@@ -43,9 +86,21 @@ module Shale
|
|
43
86
|
class NotAShaleMapperError < StandardError
|
44
87
|
end
|
45
88
|
|
46
|
-
#
|
89
|
+
# Schema compilation error
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
class SchemaError < StandardError
|
93
|
+
end
|
94
|
+
|
95
|
+
# Parsing error
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
class ParseError < StandardError
|
99
|
+
end
|
100
|
+
|
101
|
+
# Adapter error
|
47
102
|
#
|
48
103
|
# @api private
|
49
|
-
class
|
104
|
+
class AdapterError < StandardError
|
50
105
|
end
|
51
106
|
end
|