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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +449 -40
  5. data/exe/shaleb +30 -6
  6. data/lib/shale/adapter/json.rb +3 -3
  7. data/lib/shale/adapter/nokogiri/document.rb +97 -0
  8. data/lib/shale/adapter/nokogiri/node.rb +100 -0
  9. data/lib/shale/adapter/nokogiri.rb +17 -156
  10. data/lib/shale/adapter/ox/document.rb +90 -0
  11. data/lib/shale/adapter/ox/node.rb +97 -0
  12. data/lib/shale/adapter/ox.rb +14 -138
  13. data/lib/shale/adapter/rexml/document.rb +98 -0
  14. data/lib/shale/adapter/rexml/node.rb +99 -0
  15. data/lib/shale/adapter/rexml.rb +14 -154
  16. data/lib/shale/adapter/toml_rb.rb +34 -0
  17. data/lib/shale/error.rb +57 -2
  18. data/lib/shale/mapper.rb +61 -9
  19. data/lib/shale/mapping/descriptor/dict.rb +12 -1
  20. data/lib/shale/mapping/descriptor/xml.rb +12 -2
  21. data/lib/shale/mapping/dict.rb +26 -2
  22. data/lib/shale/mapping/xml.rb +52 -6
  23. data/lib/shale/schema/{json_compiler → compiler}/boolean.rb +1 -1
  24. data/lib/shale/schema/{json_compiler/object.rb → compiler/complex.rb} +11 -8
  25. data/lib/shale/schema/{json_compiler → compiler}/date.rb +1 -1
  26. data/lib/shale/schema/{json_compiler → compiler}/float.rb +1 -1
  27. data/lib/shale/schema/{json_compiler → compiler}/integer.rb +1 -1
  28. data/lib/shale/schema/{json_compiler → compiler}/property.rb +6 -6
  29. data/lib/shale/schema/{json_compiler → compiler}/string.rb +1 -1
  30. data/lib/shale/schema/{json_compiler → compiler}/time.rb +1 -1
  31. data/lib/shale/schema/compiler/value.rb +21 -0
  32. data/lib/shale/schema/compiler/xml_complex.rb +50 -0
  33. data/lib/shale/schema/compiler/xml_property.rb +73 -0
  34. data/lib/shale/schema/json_compiler.rb +32 -34
  35. data/lib/shale/schema/json_generator.rb +4 -6
  36. data/lib/shale/schema/xml_compiler.rb +919 -0
  37. data/lib/shale/schema/xml_generator/import.rb +2 -2
  38. data/lib/shale/schema/xml_generator.rb +11 -13
  39. data/lib/shale/schema.rb +16 -0
  40. data/lib/shale/type/complex.rb +763 -0
  41. data/lib/shale/type/value.rb +38 -9
  42. data/lib/shale/utils.rb +42 -7
  43. data/lib/shale/version.rb +1 -1
  44. data/lib/shale.rb +22 -19
  45. data/shale.gemspec +3 -3
  46. metadata +26 -17
  47. data/lib/shale/schema/json_compiler/utils.rb +0 -52
  48. data/lib/shale/schema/json_compiler/value.rb +0 -13
  49. data/lib/shale/type/composite.rb +0 -331
@@ -1,331 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'value'
4
-
5
- module Shale
6
- module Type
7
- # Build composite object. Don't use it directly.
8
- # It serves as a base type class for @see Shale::Mapper
9
- #
10
- # @api private
11
- class Composite < Value
12
- class << self
13
- %i[hash json yaml].each do |format|
14
- class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
15
- # Convert Hash to Object using Hash/JSON/YAML mapping
16
- #
17
- # @param [Hash] hash Hash to convert
18
- #
19
- # @return [Shale::Mapper]
20
- #
21
- # @api public
22
- def of_#{format}(hash)
23
- instance = new
24
-
25
- mapping_keys = #{format}_mapping.keys
26
-
27
- hash.each do |key, value|
28
- mapping = mapping_keys[key]
29
- next unless mapping
30
-
31
- if mapping.method_from
32
- instance.send(mapping.method_from, value)
33
- else
34
- attribute = attributes[mapping.attribute]
35
- next unless attribute
36
-
37
- if value.nil?
38
- instance.send(attribute.setter, nil)
39
- elsif attribute.collection?
40
- [*value].each do |val|
41
- val = val ? attribute.type.of_#{format}(val) : val
42
- instance.send(attribute.name) << attribute.type.cast(val)
43
- end
44
- else
45
- val = attribute.type.of_#{format}(value)
46
- instance.send(attribute.setter, val)
47
- end
48
- end
49
- end
50
-
51
- instance
52
- end
53
-
54
- # Convert Object to Hash using Hash/JSON/YAML mapping
55
- #
56
- # @param [Shale::Mapper] instance Object to convert
57
- #
58
- # @return [Hash]
59
- #
60
- # @api public
61
- def as_#{format}(instance)
62
- hash = {}
63
-
64
- instance.class.#{format}_mapping.keys.each_value do |mapping|
65
- if mapping.method_to
66
- hash[mapping.name] = instance.send(mapping.method_to)
67
- else
68
- attribute = instance.class.attributes[mapping.attribute]
69
- next unless attribute
70
-
71
- value = instance.send(attribute.name)
72
-
73
- if value.nil?
74
- hash[mapping.name] = nil
75
- elsif attribute.collection?
76
- hash[mapping.name] = [*value].map do |v|
77
- v ? attribute.type.as_#{format}(v) : v
78
- end
79
- else
80
- hash[mapping.name] = attribute.type.as_#{format}(value)
81
- end
82
- end
83
- end
84
-
85
- hash
86
- end
87
- RUBY
88
- end
89
-
90
- alias from_hash of_hash
91
-
92
- alias to_hash as_hash
93
-
94
- # Convert JSON to Object
95
- #
96
- # @param [String] json JSON to convert
97
- #
98
- # @return [Shale::Mapper]
99
- #
100
- # @api public
101
- def from_json(json)
102
- of_json(Shale.json_adapter.load(json))
103
- end
104
-
105
- # Convert Object to JSON
106
- #
107
- # @param [Shale::Mapper] instance Object to convert
108
- # @param [Array<Symbol>] options
109
- #
110
- # @return [String]
111
- #
112
- # @api public
113
- def to_json(instance, *options)
114
- Shale.json_adapter.dump(as_json(instance), *options)
115
- end
116
-
117
- # Convert YAML to Object
118
- #
119
- # @param [String] yaml YAML to convert
120
- #
121
- # @return [Shale::Mapper]
122
- #
123
- # @api public
124
- def from_yaml(yaml)
125
- of_yaml(Shale.yaml_adapter.load(yaml))
126
- end
127
-
128
- # Convert Object to YAML
129
- #
130
- # @param [Shale::Mapper] instance Object to convert
131
- #
132
- # @return [String]
133
- #
134
- # @api public
135
- def to_yaml(instance)
136
- Shale.yaml_adapter.dump(as_yaml(instance))
137
- end
138
-
139
- # Convert XML document to Object
140
- #
141
- # @param [Shale::Adapter::<XML adapter>::Node] xml XML to convert
142
- #
143
- # @return [Shale::Mapper]
144
- #
145
- # @api public
146
- def of_xml(element)
147
- instance = new
148
-
149
- element.attributes.each do |key, value|
150
- mapping = xml_mapping.attributes[key.to_s]
151
- next unless mapping
152
-
153
- if mapping.method_from
154
- instance.send(mapping.method_from, value)
155
- else
156
- attribute = attributes[mapping.attribute]
157
- next unless attribute
158
-
159
- if attribute.collection?
160
- instance.send(attribute.name) << attribute.type.cast(value)
161
- else
162
- instance.send(attribute.setter, value)
163
- end
164
- end
165
- end
166
-
167
- if xml_mapping.content
168
- attribute = attributes[xml_mapping.content]
169
-
170
- if attribute
171
- instance.send(attribute.setter, attribute.type.of_xml(element))
172
- end
173
- end
174
-
175
- element.children.each do |node|
176
- mapping = xml_mapping.elements[node.name]
177
- next unless mapping
178
-
179
- if mapping.method_from
180
- instance.send(mapping.method_from, node)
181
- else
182
- attribute = attributes[mapping.attribute]
183
- next unless attribute
184
-
185
- if attribute.collection?
186
- value = attribute.type.of_xml(node)
187
- instance.send(attribute.name) << attribute.type.cast(value)
188
- else
189
- instance.send(attribute.setter, attribute.type.of_xml(node))
190
- end
191
- end
192
- end
193
-
194
- instance
195
- end
196
-
197
- # Convert XML to Object
198
- #
199
- # @param [String] xml XML to convert
200
- #
201
- # @return [Shale::Mapper]
202
- #
203
- # @api public
204
- def from_xml(xml)
205
- of_xml(Shale.xml_adapter.load(xml))
206
- end
207
-
208
- # Convert Object to XML document
209
- #
210
- # @param [Shale::Mapper] instance Object to convert
211
- # @param [String, nil] node_name XML node name
212
- # @param [Shale::Adapter::<xml adapter>::Document, nil] doc Object to convert
213
- #
214
- # @return [::REXML::Document, ::Nokogiri::Document, ::Ox::Document]
215
- #
216
- # @api public
217
- def as_xml(instance, node_name = nil, doc = nil)
218
- unless doc
219
- doc = Shale.xml_adapter.create_document
220
- doc.add_element(doc.doc, as_xml(instance, xml_mapping.prefixed_root, doc))
221
- return doc.doc
222
- end
223
-
224
- element = doc.create_element(node_name)
225
- doc.add_namespace(xml_mapping.default_namespace.prefix, xml_mapping.default_namespace.name)
226
-
227
- xml_mapping.attributes.each_value do |mapping|
228
- if mapping.method_to
229
- instance.send(mapping.method_to, element, doc)
230
- else
231
- attribute = instance.class.attributes[mapping.attribute]
232
- next unless attribute
233
-
234
- value = instance.send(attribute.name)
235
- next if value.nil?
236
-
237
- doc.add_namespace(mapping.namespace.prefix, mapping.namespace.name)
238
- doc.add_attribute(element, mapping.prefixed_name, value)
239
- end
240
- end
241
-
242
- if xml_mapping.content
243
- attribute = instance.class.attributes[xml_mapping.content]
244
-
245
- if attribute
246
- value = instance.send(attribute.name)
247
- doc.add_text(element, value.to_s) if value
248
- end
249
- end
250
-
251
- xml_mapping.elements.each_value do |mapping|
252
- if mapping.method_to
253
- instance.send(mapping.method_to, element, doc)
254
- else
255
- attribute = instance.class.attributes[mapping.attribute]
256
- next unless attribute
257
-
258
- value = instance.send(attribute.name)
259
- next if value.nil?
260
-
261
- doc.add_namespace(mapping.namespace.prefix, mapping.namespace.name)
262
-
263
- if attribute.collection?
264
- [*value].each do |v|
265
- next if v.nil?
266
- doc.add_element(element, attribute.type.as_xml(v, mapping.prefixed_name, doc))
267
- end
268
- else
269
- doc.add_element(element, attribute.type.as_xml(value, mapping.prefixed_name, doc))
270
- end
271
- end
272
- end
273
-
274
- element
275
- end
276
-
277
- # Convert Object to XML
278
- #
279
- # @param [Shale::Mapper] instance Object to convert
280
- # @param [Array<Symbol>] options
281
- #
282
- # @return [String]
283
- #
284
- # @api public
285
- def to_xml(instance, *options)
286
- Shale.xml_adapter.dump(as_xml(instance), *options)
287
- end
288
- end
289
-
290
- # Convert Object to Hash
291
- #
292
- # @return [Hash]
293
- #
294
- # @api public
295
- def to_hash
296
- self.class.to_hash(self)
297
- end
298
-
299
- # Convert Object to JSON
300
- #
301
- # @param [Array<Symbol>] options
302
- #
303
- # @return [String]
304
- #
305
- # @api public
306
- def to_json(*options)
307
- self.class.to_json(self, *options)
308
- end
309
-
310
- # Convert Object to YAML
311
- #
312
- # @return [String]
313
- #
314
- # @api public
315
- def to_yaml
316
- self.class.to_yaml(self)
317
- end
318
-
319
- # Convert Object to XML
320
- #
321
- # @param [Array<Symbol>] options
322
- #
323
- # @return [String]
324
- #
325
- # @api public
326
- def to_xml(*options)
327
- self.class.to_xml(self, *options)
328
- end
329
- end
330
- end
331
- end