shale 0.4.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|