shale 0.4.0 → 0.7.0

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