shale 0.8.0 → 1.0.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 +24 -0
- data/README.md +313 -62
- data/exe/shaleb +19 -4
- data/lib/shale/adapter/csv.rb +48 -0
- data/lib/shale/adapter/nokogiri/document.rb +7 -2
- data/lib/shale/adapter/nokogiri.rb +11 -4
- data/lib/shale/adapter/ox.rb +10 -4
- data/lib/shale/adapter/rexml.rb +18 -4
- data/lib/shale/error.rb +20 -8
- data/lib/shale/mapper.rb +41 -6
- data/lib/shale/mapping/delegates.rb +95 -0
- data/lib/shale/mapping/descriptor/dict.rb +10 -1
- data/lib/shale/mapping/descriptor/xml.rb +13 -2
- data/lib/shale/mapping/dict.rb +15 -5
- data/lib/shale/mapping/dict_base.rb +12 -6
- data/lib/shale/mapping/dict_group.rb +1 -1
- data/lib/shale/mapping/validator.rb +10 -3
- data/lib/shale/mapping/xml.rb +22 -6
- data/lib/shale/mapping/xml_base.rb +21 -12
- data/lib/shale/schema/compiler/complex.rb +52 -8
- data/lib/shale/schema/compiler/xml_complex.rb +5 -4
- data/lib/shale/schema/json_compiler.rb +27 -13
- data/lib/shale/schema/json_generator.rb +2 -2
- data/lib/shale/schema/xml_compiler.rb +46 -18
- data/lib/shale/schema/xml_generator.rb +3 -3
- data/lib/shale/schema.rb +10 -4
- data/lib/shale/type/complex.rb +291 -34
- data/lib/shale/type/date.rb +11 -0
- data/lib/shale/type/time.rb +11 -0
- data/lib/shale/type/value.rb +22 -0
- data/lib/shale/utils.rb +22 -4
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +30 -4
- data/shale.gemspec +2 -2
- metadata +7 -5
@@ -9,9 +9,14 @@ module Shale
|
|
9
9
|
class Document
|
10
10
|
# Initialize object
|
11
11
|
#
|
12
|
+
# @param [String, nil] version
|
13
|
+
#
|
12
14
|
# @api private
|
13
|
-
def initialize
|
14
|
-
|
15
|
+
def initialize(version = nil)
|
16
|
+
ver = nil
|
17
|
+
ver = version if version.is_a?(String)
|
18
|
+
|
19
|
+
@doc = ::Nokogiri::XML::Document.new(ver)
|
15
20
|
@namespaces = {}
|
16
21
|
end
|
17
22
|
|
@@ -37,12 +37,13 @@ module Shale
|
|
37
37
|
#
|
38
38
|
# @param [::Nokogiri::XML::Document] doc Nokogiri document
|
39
39
|
# @param [true, false] pretty
|
40
|
-
# @param [true, false] declaration
|
40
|
+
# @param [true, false, String] declaration
|
41
|
+
# @param [true, false, String] encoding
|
41
42
|
#
|
42
43
|
# @return [String]
|
43
44
|
#
|
44
45
|
# @api private
|
45
|
-
def self.dump(doc, pretty: false, declaration: false)
|
46
|
+
def self.dump(doc, pretty: false, declaration: false, encoding: false)
|
46
47
|
save_with = ::Nokogiri::XML::Node::SaveOptions::AS_XML
|
47
48
|
|
48
49
|
if pretty
|
@@ -53,6 +54,10 @@ module Shale
|
|
53
54
|
save_with |= ::Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
|
54
55
|
end
|
55
56
|
|
57
|
+
if encoding
|
58
|
+
doc.encoding = encoding == true ? 'UTF-8' : encoding
|
59
|
+
end
|
60
|
+
|
56
61
|
result = doc.to_xml(save_with: save_with)
|
57
62
|
|
58
63
|
unless pretty
|
@@ -64,9 +69,11 @@ module Shale
|
|
64
69
|
|
65
70
|
# Create Shale::Adapter::Nokogiri::Document instance
|
66
71
|
#
|
72
|
+
# @param [true, false, String, nil] declaration
|
73
|
+
#
|
67
74
|
# @api private
|
68
|
-
def self.create_document
|
69
|
-
Document.new
|
75
|
+
def self.create_document(version = nil)
|
76
|
+
Document.new(version)
|
70
77
|
end
|
71
78
|
end
|
72
79
|
end
|
data/lib/shale/adapter/ox.rb
CHANGED
@@ -31,12 +31,13 @@ module Shale
|
|
31
31
|
#
|
32
32
|
# @param [::Ox::Document, ::Ox::Element] doc Ox document
|
33
33
|
# @param [true, false] pretty
|
34
|
-
# @param [true, false] declaration
|
34
|
+
# @param [true, false, String] declaration
|
35
|
+
# @param [true, false, String] encoding
|
35
36
|
#
|
36
37
|
# @return [String]
|
37
38
|
#
|
38
39
|
# @api private
|
39
|
-
def self.dump(doc, pretty: false, declaration: false)
|
40
|
+
def self.dump(doc, pretty: false, declaration: false, encoding: false)
|
40
41
|
opts = { indent: -1, with_xml: false }
|
41
42
|
|
42
43
|
if pretty
|
@@ -44,7 +45,12 @@ module Shale
|
|
44
45
|
end
|
45
46
|
|
46
47
|
if declaration
|
47
|
-
doc[:version] = '1.0'
|
48
|
+
doc[:version] = declaration == true ? '1.0' : declaration
|
49
|
+
|
50
|
+
if encoding
|
51
|
+
doc[:encoding] = encoding == true ? 'UTF-8' : encoding
|
52
|
+
end
|
53
|
+
|
48
54
|
opts[:with_xml] = true
|
49
55
|
end
|
50
56
|
|
@@ -54,7 +60,7 @@ module Shale
|
|
54
60
|
# Create Shale::Adapter::Ox::Document instance
|
55
61
|
#
|
56
62
|
# @api private
|
57
|
-
def self.create_document
|
63
|
+
def self.create_document(_version = nil)
|
58
64
|
Document.new
|
59
65
|
end
|
60
66
|
end
|
data/lib/shale/adapter/rexml.rb
CHANGED
@@ -32,14 +32,28 @@ module Shale
|
|
32
32
|
#
|
33
33
|
# @param [::REXML::Document] doc REXML document
|
34
34
|
# @param [true, false] pretty
|
35
|
-
# @param [true, false] declaration
|
35
|
+
# @param [true, false, String] declaration
|
36
|
+
# @param [true, false, String] encoding
|
36
37
|
#
|
37
38
|
# @return [String]
|
38
39
|
#
|
39
40
|
# @api private
|
40
|
-
def self.dump(doc, pretty: false, declaration: false)
|
41
|
+
def self.dump(doc, pretty: false, declaration: false, encoding: false)
|
41
42
|
if declaration
|
42
|
-
|
43
|
+
ver = nil
|
44
|
+
enc = nil
|
45
|
+
|
46
|
+
if declaration.is_a?(String)
|
47
|
+
ver = declaration
|
48
|
+
end
|
49
|
+
|
50
|
+
if encoding == true
|
51
|
+
enc = 'UTF-8'
|
52
|
+
else
|
53
|
+
enc = encoding || nil
|
54
|
+
end
|
55
|
+
|
56
|
+
doc.add(::REXML::XMLDecl.new(ver, enc))
|
43
57
|
end
|
44
58
|
|
45
59
|
io = StringIO.new
|
@@ -58,7 +72,7 @@ module Shale
|
|
58
72
|
# Create Shale::Adapter::REXML::Document instance
|
59
73
|
#
|
60
74
|
# @api private
|
61
|
-
def self.create_document
|
75
|
+
def self.create_document(_version = nil)
|
62
76
|
Document.new
|
63
77
|
end
|
64
78
|
end
|
data/lib/shale/error.rb
CHANGED
@@ -53,10 +53,16 @@ module Shale
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
# Shale base error class
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
class ShaleError < StandardError
|
60
|
+
end
|
61
|
+
|
56
62
|
# Error for trying to assign not callable object as an attribute's default
|
57
63
|
#
|
58
64
|
# @api private
|
59
|
-
class DefaultNotCallableError <
|
65
|
+
class DefaultNotCallableError < ShaleError
|
60
66
|
# Initialize error object
|
61
67
|
#
|
62
68
|
# @param [String] record
|
@@ -71,36 +77,42 @@ module Shale
|
|
71
77
|
# Error for passing incorrect model type
|
72
78
|
#
|
73
79
|
# @api private
|
74
|
-
class IncorrectModelError <
|
80
|
+
class IncorrectModelError < ShaleError
|
75
81
|
end
|
76
82
|
|
77
83
|
# Error for passing incorrect arguments to map functions
|
78
84
|
#
|
79
85
|
# @api private
|
80
|
-
class IncorrectMappingArgumentsError <
|
86
|
+
class IncorrectMappingArgumentsError < ShaleError
|
87
|
+
end
|
88
|
+
|
89
|
+
# Error for using incorrect type
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
class NotAShaleMapperError < ShaleError
|
81
93
|
end
|
82
94
|
|
83
|
-
#
|
95
|
+
# Raised when receiver attribute is not defined
|
84
96
|
#
|
85
97
|
# @api private
|
86
|
-
class
|
98
|
+
class AttributeNotDefinedError < ShaleError
|
87
99
|
end
|
88
100
|
|
89
101
|
# Schema compilation error
|
90
102
|
#
|
91
103
|
# @api private
|
92
|
-
class SchemaError <
|
104
|
+
class SchemaError < ShaleError
|
93
105
|
end
|
94
106
|
|
95
107
|
# Parsing error
|
96
108
|
#
|
97
109
|
# @api private
|
98
|
-
class ParseError <
|
110
|
+
class ParseError < ShaleError
|
99
111
|
end
|
100
112
|
|
101
113
|
# Adapter error
|
102
114
|
#
|
103
115
|
# @api private
|
104
|
-
class AdapterError <
|
116
|
+
class AdapterError < ShaleError
|
105
117
|
end
|
106
118
|
end
|
data/lib/shale/mapper.rb
CHANGED
@@ -49,6 +49,7 @@ module Shale
|
|
49
49
|
@json_mapping = Mapping::Dict.new
|
50
50
|
@yaml_mapping = Mapping::Dict.new
|
51
51
|
@toml_mapping = Mapping::Dict.new
|
52
|
+
@csv_mapping = Mapping::Dict.new(render_nil_default: true)
|
52
53
|
@xml_mapping = Mapping::Xml.new
|
53
54
|
|
54
55
|
class << self
|
@@ -87,6 +88,13 @@ module Shale
|
|
87
88
|
# @api public
|
88
89
|
attr_reader :toml_mapping
|
89
90
|
|
91
|
+
# Return CSV mapping object
|
92
|
+
#
|
93
|
+
# @return [Shale::Mapping::Dict]
|
94
|
+
#
|
95
|
+
# @api public
|
96
|
+
attr_reader :csv_mapping
|
97
|
+
|
90
98
|
# Return XML mapping object
|
91
99
|
#
|
92
100
|
# @return [Shale::Mapping::XML]
|
@@ -109,12 +117,14 @@ module Shale
|
|
109
117
|
subclass.instance_variable_set('@__json_mapping_init', @json_mapping.dup)
|
110
118
|
subclass.instance_variable_set('@__yaml_mapping_init', @yaml_mapping.dup)
|
111
119
|
subclass.instance_variable_set('@__toml_mapping_init', @toml_mapping.dup)
|
120
|
+
subclass.instance_variable_set('@__csv_mapping_init', @csv_mapping.dup)
|
112
121
|
subclass.instance_variable_set('@__xml_mapping_init', @xml_mapping.dup)
|
113
122
|
|
114
123
|
subclass.instance_variable_set('@hash_mapping', @hash_mapping.dup)
|
115
124
|
subclass.instance_variable_set('@json_mapping', @json_mapping.dup)
|
116
125
|
subclass.instance_variable_set('@yaml_mapping', @yaml_mapping.dup)
|
117
126
|
subclass.instance_variable_set('@toml_mapping', @toml_mapping.dup)
|
127
|
+
subclass.instance_variable_set('@csv_mapping', @csv_mapping.dup)
|
118
128
|
|
119
129
|
xml_mapping = @xml_mapping.dup
|
120
130
|
xml_mapping.root(Utils.underscore(subclass.name || ''))
|
@@ -141,7 +151,7 @@ module Shale
|
|
141
151
|
# @raise [DefaultNotCallableError] when attribute's default is not callable
|
142
152
|
#
|
143
153
|
# @example
|
144
|
-
#
|
154
|
+
# class Person < Shale::Mapper
|
145
155
|
# attribute :first_name, Shale::Type::String
|
146
156
|
# attribute :last_name, Shale::Type::String
|
147
157
|
# attribute :age, Shale::Type::Integer, default: -> { 1 }
|
@@ -173,6 +183,7 @@ module Shale
|
|
173
183
|
@json_mapping.map(name.to_s, to: name) unless @json_mapping.finalized?
|
174
184
|
@yaml_mapping.map(name.to_s, to: name) unless @yaml_mapping.finalized?
|
175
185
|
@toml_mapping.map(name.to_s, to: name) unless @toml_mapping.finalized?
|
186
|
+
@csv_mapping.map(name.to_s, to: name) unless @csv_mapping.finalized?
|
176
187
|
@xml_mapping.map_element(name.to_s, to: name) unless @xml_mapping.finalized?
|
177
188
|
|
178
189
|
@attributes_module.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
@@ -189,7 +200,7 @@ module Shale
|
|
189
200
|
# @param [Proc] block
|
190
201
|
#
|
191
202
|
# @example
|
192
|
-
#
|
203
|
+
# class Person < Shale::Mapper
|
193
204
|
# attribute :first_name, Shale::Type::String
|
194
205
|
# attribute :last_name, Shale::Type::String
|
195
206
|
# attribute :age, Shale::Type::Integer
|
@@ -213,7 +224,7 @@ module Shale
|
|
213
224
|
# @param [Proc] block
|
214
225
|
#
|
215
226
|
# @example
|
216
|
-
#
|
227
|
+
# class Person < Shale::Mapper
|
217
228
|
# attribute :first_name, Shale::Type::String
|
218
229
|
# attribute :last_name, Shale::Type::String
|
219
230
|
# attribute :age, Shale::Type::Integer
|
@@ -237,7 +248,7 @@ module Shale
|
|
237
248
|
# @param [Proc] block
|
238
249
|
#
|
239
250
|
# @example
|
240
|
-
#
|
251
|
+
# class Person < Shale::Mapper
|
241
252
|
# attribute :first_name, Shale::Type::String
|
242
253
|
# attribute :last_name, Shale::Type::String
|
243
254
|
# attribute :age, Shale::Type::Integer
|
@@ -261,7 +272,7 @@ module Shale
|
|
261
272
|
# @param [Proc] block
|
262
273
|
#
|
263
274
|
# @example
|
264
|
-
#
|
275
|
+
# class Person < Shale::Mapper
|
265
276
|
# attribute :first_name, Shale::Type::String
|
266
277
|
# attribute :last_name, Shale::Type::String
|
267
278
|
# attribute :age, Shale::Type::Integer
|
@@ -280,12 +291,36 @@ module Shale
|
|
280
291
|
@toml_mapping.instance_eval(&block)
|
281
292
|
end
|
282
293
|
|
294
|
+
# Define CSV mapping
|
295
|
+
#
|
296
|
+
# @param [Proc] block
|
297
|
+
#
|
298
|
+
# @example
|
299
|
+
# class Person < Shale::Mapper
|
300
|
+
# attribute :first_name, Shale::Type::String
|
301
|
+
# attribute :last_name, Shale::Type::String
|
302
|
+
# attribute :age, Shale::Type::Integer
|
303
|
+
#
|
304
|
+
# csv do
|
305
|
+
# map 'first_name', to: :first_name
|
306
|
+
# map 'last_name', to: :last_name
|
307
|
+
# map 'age', to: :age
|
308
|
+
# end
|
309
|
+
# end
|
310
|
+
#
|
311
|
+
# @api public
|
312
|
+
def csv(&block)
|
313
|
+
@csv_mapping = @__csv_mapping_init.dup
|
314
|
+
@csv_mapping.finalize!
|
315
|
+
@csv_mapping.instance_eval(&block)
|
316
|
+
end
|
317
|
+
|
283
318
|
# Define XML mapping
|
284
319
|
#
|
285
320
|
# @param [Proc] block
|
286
321
|
#
|
287
322
|
# @example
|
288
|
-
#
|
323
|
+
# class Person < Shale::Mapper
|
289
324
|
# attribute :first_name, Shale::Type::String
|
290
325
|
# attribute :last_name, Shale::Type::String
|
291
326
|
# attribute :age, Shale::Type::Integer
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Mapping
|
5
|
+
# Class for handling attribute delegation
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class Delegates
|
9
|
+
# Class representing individual delegation
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class Delegate
|
13
|
+
# Return receiver_attribute
|
14
|
+
#
|
15
|
+
# @return [Shale::Attribute]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
attr_reader :receiver_attribute
|
19
|
+
|
20
|
+
# Return attribute setter on a delegate
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
attr_reader :setter
|
26
|
+
|
27
|
+
# Return value to set on a delegate
|
28
|
+
#
|
29
|
+
# @return [any]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
attr_reader :value
|
33
|
+
|
34
|
+
# Initialize instance
|
35
|
+
#
|
36
|
+
# @param [Shale::Attribute] receiver_attribute
|
37
|
+
# @param [String] setter
|
38
|
+
# @param [any] value
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def initialize(receiver_attribute, setter, value)
|
42
|
+
@receiver_attribute = receiver_attribute
|
43
|
+
@setter = setter
|
44
|
+
@value = value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initialize instance
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
def initialize
|
52
|
+
@delegates = []
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add single value to delegate
|
56
|
+
#
|
57
|
+
# @param [Shale::Attribute] receiver_attribute
|
58
|
+
# @param [String] setter
|
59
|
+
# @param [any] value
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
def add(receiver_attribute, setter, value)
|
63
|
+
@delegates << Delegate.new(receiver_attribute, setter, value)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add collection to delegate
|
67
|
+
#
|
68
|
+
# @param [Shale::Attribute] receiver_attribute
|
69
|
+
# @param [String] setter
|
70
|
+
# @param [any] value
|
71
|
+
#
|
72
|
+
# @api private
|
73
|
+
def add_collection(receiver_attribute, setter, value)
|
74
|
+
delegate = @delegates.find do |e|
|
75
|
+
e.receiver_attribute == receiver_attribute && e.setter == setter
|
76
|
+
end
|
77
|
+
|
78
|
+
if delegate
|
79
|
+
delegate.value << value
|
80
|
+
else
|
81
|
+
@delegates << Delegate.new(receiver_attribute, setter, [value])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Iterate over delegates and yield a block
|
86
|
+
#
|
87
|
+
# @param [Proc] block
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
def each(&block)
|
91
|
+
@delegates.each(&block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -21,6 +21,13 @@ module Shale
|
|
21
21
|
# @api private
|
22
22
|
attr_reader :attribute
|
23
23
|
|
24
|
+
# Return receiver name
|
25
|
+
#
|
26
|
+
# @return [Symbol]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
attr_reader :receiver
|
30
|
+
|
24
31
|
# Return method symbol
|
25
32
|
#
|
26
33
|
# @return [Symbol]
|
@@ -46,14 +53,16 @@ module Shale
|
|
46
53
|
#
|
47
54
|
# @param [String] name
|
48
55
|
# @param [Symbol, nil] attribute
|
56
|
+
# @param [Symbol, nil] receiver
|
49
57
|
# @param [Hash, nil] methods
|
50
58
|
# @param [String, nil] group
|
51
59
|
# @param [true, false] render_nil
|
52
60
|
#
|
53
61
|
# @api private
|
54
|
-
def initialize(name:, attribute:, methods:, group:, render_nil:)
|
62
|
+
def initialize(name:, attribute:, receiver:, methods:, group:, render_nil:)
|
55
63
|
@name = name
|
56
64
|
@attribute = attribute
|
65
|
+
@receiver = receiver
|
57
66
|
@group = group
|
58
67
|
@render_nil = render_nil
|
59
68
|
|
@@ -26,7 +26,8 @@ module Shale
|
|
26
26
|
# Initialize instance
|
27
27
|
#
|
28
28
|
# @param [String] name
|
29
|
-
# @param [Symbol,
|
29
|
+
# @param [Symbol, nil] attribute
|
30
|
+
# @param [Symbol, nil] receiver
|
30
31
|
# @param [Hash, nil] methods
|
31
32
|
# @param [String, nil] group
|
32
33
|
# @param [Shale::Mapping::XmlNamespace] namespace
|
@@ -34,10 +35,20 @@ module Shale
|
|
34
35
|
# @param [true, false] render_nil
|
35
36
|
#
|
36
37
|
# @api private
|
37
|
-
def initialize(
|
38
|
+
def initialize(
|
39
|
+
name:,
|
40
|
+
attribute:,
|
41
|
+
receiver:,
|
42
|
+
methods:,
|
43
|
+
group:,
|
44
|
+
namespace:,
|
45
|
+
cdata:,
|
46
|
+
render_nil:
|
47
|
+
)
|
38
48
|
super(
|
39
49
|
name: name,
|
40
50
|
attribute: attribute,
|
51
|
+
receiver: receiver,
|
41
52
|
methods: methods,
|
42
53
|
group: group,
|
43
54
|
render_nil: render_nil
|
data/lib/shale/mapping/dict.rb
CHANGED
@@ -5,22 +5,32 @@ require_relative 'dict_group'
|
|
5
5
|
|
6
6
|
module Shale
|
7
7
|
module Mapping
|
8
|
-
# Mapping for dictionary serialization formats (Hash/JSON/YAML)
|
8
|
+
# Mapping for dictionary serialization formats (Hash/JSON/YAML/TOML/CSV)
|
9
9
|
#
|
10
10
|
# @api private
|
11
11
|
class Dict < DictBase
|
12
12
|
# Map key to attribute
|
13
13
|
#
|
14
14
|
# @param [String] key Document's key
|
15
|
-
# @param [Symbol, nil] to
|
15
|
+
# @param [Symbol, nil] to
|
16
|
+
# @param [Symbol, nil] receiver
|
16
17
|
# @param [Hash, nil] using
|
17
|
-
# @param [true, false] render_nil
|
18
|
+
# @param [true, false, nil] render_nil
|
18
19
|
#
|
19
20
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
20
21
|
#
|
21
22
|
# @api private
|
22
|
-
def map(key, to: nil, using: nil, render_nil:
|
23
|
-
super(key, to: to, using: using, render_nil: render_nil)
|
23
|
+
def map(key, to: nil, receiver: nil, using: nil, render_nil: nil)
|
24
|
+
super(key, to: to, receiver: receiver, using: using, render_nil: render_nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Set render_nil default
|
28
|
+
#
|
29
|
+
# @param [true, false] val
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
def render_nil(val)
|
33
|
+
@render_nil_default = val
|
24
34
|
end
|
25
35
|
|
26
36
|
# Map group of keys to mapping methods
|
@@ -5,7 +5,7 @@ require_relative 'validator'
|
|
5
5
|
|
6
6
|
module Shale
|
7
7
|
module Mapping
|
8
|
-
# Base class for Mapping dictionary serialization formats (Hash/JSON/YAML)
|
8
|
+
# Base class for Mapping dictionary serialization formats (Hash/JSON/YAML/TOML/CSV)
|
9
9
|
#
|
10
10
|
# @api private
|
11
11
|
class DictBase
|
@@ -18,31 +18,37 @@ module Shale
|
|
18
18
|
|
19
19
|
# Initialize instance
|
20
20
|
#
|
21
|
+
# @param [true, false] render_nil_default
|
22
|
+
#
|
21
23
|
# @api private
|
22
|
-
def initialize
|
24
|
+
def initialize(render_nil_default: false)
|
23
25
|
@keys = {}
|
24
26
|
@finalized = false
|
27
|
+
@render_nil_default = render_nil_default
|
25
28
|
end
|
26
29
|
|
27
30
|
# Map key to attribute
|
28
31
|
#
|
29
32
|
# @param [String] key
|
30
33
|
# @param [Symbol, nil] to
|
34
|
+
# @param [Symbol, nil] receiver
|
31
35
|
# @param [Hash, nil] using
|
32
36
|
# @param [String, nil] group
|
33
|
-
# @param [true, false] render_nil
|
37
|
+
# @param [true, false, nil] render_nil
|
34
38
|
#
|
35
39
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
36
40
|
#
|
37
41
|
# @api private
|
38
|
-
def map(key, to: nil, using: nil, group: nil, render_nil:
|
39
|
-
Validator.validate_arguments(key, to, using)
|
42
|
+
def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil)
|
43
|
+
Validator.validate_arguments(key, to, receiver, using)
|
44
|
+
|
40
45
|
@keys[key] = Descriptor::Dict.new(
|
41
46
|
name: key,
|
42
47
|
attribute: to,
|
48
|
+
receiver: receiver,
|
43
49
|
methods: using,
|
44
50
|
group: group,
|
45
|
-
render_nil: render_nil
|
51
|
+
render_nil: render_nil.nil? ? @render_nil_default : render_nil
|
46
52
|
)
|
47
53
|
end
|
48
54
|
|
@@ -8,18 +8,25 @@ module Shale
|
|
8
8
|
# Validate correctness of argument passed to map functions
|
9
9
|
#
|
10
10
|
# @param [String] key
|
11
|
-
# @param [Symbol] to
|
12
|
-
# @param [
|
11
|
+
# @param [Symbol, nil] to
|
12
|
+
# @param [Symbol, nil] receiver
|
13
|
+
# @param [Hash, nil] using
|
13
14
|
#
|
14
15
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
15
16
|
#
|
16
17
|
# @api private
|
17
|
-
def self.validate_arguments(key, to, using)
|
18
|
+
def self.validate_arguments(key, to, receiver, using)
|
18
19
|
if to.nil? && using.nil?
|
19
20
|
msg = ":to or :using argument is required for mapping '#{key}'"
|
20
21
|
raise IncorrectMappingArgumentsError, msg
|
21
22
|
end
|
22
23
|
|
24
|
+
if to.nil? && !receiver.nil?
|
25
|
+
msg = ":receiver argument for mapping '#{key}' " \
|
26
|
+
'can only be used together with :to argument'
|
27
|
+
raise IncorrectMappingArgumentsError, msg
|
28
|
+
end
|
29
|
+
|
23
30
|
if !using.nil? && (using[:from].nil? || using[:to].nil?)
|
24
31
|
msg = ":using argument for mapping '#{key}' requires :to and :from keys"
|
25
32
|
raise IncorrectMappingArgumentsError, msg
|