shale 0.2.2 → 0.4.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +366 -8
  4. data/exe/shaleb +123 -0
  5. data/lib/shale/adapter/json.rb +7 -2
  6. data/lib/shale/adapter/nokogiri.rb +48 -12
  7. data/lib/shale/adapter/ox.rb +28 -4
  8. data/lib/shale/adapter/rexml.rb +56 -13
  9. data/lib/shale/attribute.rb +7 -1
  10. data/lib/shale/error.rb +12 -0
  11. data/lib/shale/mapper.rb +17 -15
  12. data/lib/shale/mapping/descriptor/dict.rb +57 -0
  13. data/lib/shale/mapping/descriptor/xml.rb +43 -0
  14. data/lib/shale/mapping/descriptor/xml_namespace.rb +37 -0
  15. data/lib/shale/mapping/{key_value.rb → dict.rb} +8 -6
  16. data/lib/shale/mapping/validator.rb +51 -0
  17. data/lib/shale/mapping/xml.rb +86 -15
  18. data/lib/shale/schema/json_compiler/boolean.rb +21 -0
  19. data/lib/shale/schema/json_compiler/date.rb +21 -0
  20. data/lib/shale/schema/json_compiler/float.rb +21 -0
  21. data/lib/shale/schema/json_compiler/integer.rb +21 -0
  22. data/lib/shale/schema/json_compiler/object.rb +85 -0
  23. data/lib/shale/schema/json_compiler/property.rb +70 -0
  24. data/lib/shale/schema/json_compiler/string.rb +21 -0
  25. data/lib/shale/schema/json_compiler/time.rb +21 -0
  26. data/lib/shale/schema/json_compiler/utils.rb +52 -0
  27. data/lib/shale/schema/json_compiler/value.rb +13 -0
  28. data/lib/shale/schema/json_compiler.rb +333 -0
  29. data/lib/shale/schema/json_generator/base.rb +41 -0
  30. data/lib/shale/schema/json_generator/boolean.rb +23 -0
  31. data/lib/shale/schema/json_generator/collection.rb +39 -0
  32. data/lib/shale/schema/json_generator/date.rb +23 -0
  33. data/lib/shale/schema/json_generator/float.rb +23 -0
  34. data/lib/shale/schema/json_generator/integer.rb +23 -0
  35. data/lib/shale/schema/json_generator/object.rb +40 -0
  36. data/lib/shale/schema/json_generator/ref.rb +28 -0
  37. data/lib/shale/schema/json_generator/schema.rb +59 -0
  38. data/lib/shale/schema/json_generator/string.rb +23 -0
  39. data/lib/shale/schema/json_generator/time.rb +23 -0
  40. data/lib/shale/schema/json_generator/value.rb +23 -0
  41. data/lib/shale/schema/json_generator.rb +165 -0
  42. data/lib/shale/schema/xml_generator/attribute.rb +41 -0
  43. data/lib/shale/schema/xml_generator/complex_type.rb +70 -0
  44. data/lib/shale/schema/xml_generator/element.rb +55 -0
  45. data/lib/shale/schema/xml_generator/import.rb +46 -0
  46. data/lib/shale/schema/xml_generator/ref_attribute.rb +37 -0
  47. data/lib/shale/schema/xml_generator/ref_element.rb +39 -0
  48. data/lib/shale/schema/xml_generator/schema.rb +121 -0
  49. data/lib/shale/schema/xml_generator/typed_attribute.rb +46 -0
  50. data/lib/shale/schema/xml_generator/typed_element.rb +46 -0
  51. data/lib/shale/schema/xml_generator.rb +315 -0
  52. data/lib/shale/schema.rb +70 -0
  53. data/lib/shale/type/boolean.rb +2 -2
  54. data/lib/shale/type/composite.rb +78 -72
  55. data/lib/shale/type/date.rb +35 -2
  56. data/lib/shale/type/float.rb +2 -2
  57. data/lib/shale/type/integer.rb +2 -2
  58. data/lib/shale/type/string.rb +2 -2
  59. data/lib/shale/type/time.rb +35 -2
  60. data/lib/shale/type/{base.rb → value.rb} +18 -7
  61. data/lib/shale/utils.rb +18 -2
  62. data/lib/shale/version.rb +1 -1
  63. data/lib/shale.rb +10 -10
  64. data/shale.gemspec +6 -2
  65. metadata +53 -13
  66. data/lib/shale/mapping/base.rb +0 -32
@@ -26,12 +26,29 @@ module Shale
26
26
  # Serialize Nokogiri document into XML
27
27
  #
28
28
  # @param [::Nokogiri::XML::Document] doc Nokogiri document
29
+ # @param [Array<Symbol>] options
29
30
  #
30
31
  # @return [String]
31
32
  #
32
33
  # @api private
33
- def self.dump(doc)
34
- doc.to_xml
34
+ def self.dump(doc, *options)
35
+ save_with = ::Nokogiri::XML::Node::SaveOptions::AS_XML
36
+
37
+ if options.include?(:pretty)
38
+ save_with |= ::Nokogiri::XML::Node::SaveOptions::FORMAT
39
+ end
40
+
41
+ unless options.include?(:declaration)
42
+ save_with |= ::Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
43
+ end
44
+
45
+ result = doc.to_xml(save_with: save_with)
46
+
47
+ unless options.include?(:pretty)
48
+ result = result.sub(/\n/, '')
49
+ end
50
+
51
+ result
35
52
  end
36
53
 
37
54
  # Create Shale::Adapter::Nokogiri::Document instance
@@ -45,18 +62,27 @@ module Shale
45
62
  #
46
63
  # @api private
47
64
  class Document
65
+ # Initialize object
66
+ #
67
+ # @api private
68
+ def initialize
69
+ @doc = ::Nokogiri::XML::Document.new
70
+ @namespaces = {}
71
+ end
72
+
48
73
  # Return Nokogiri document
49
74
  #
50
75
  # @return [::Nokogiri::XML::Document]
51
76
  #
52
77
  # @api private
53
- attr_reader :doc
78
+ def doc
79
+ if @doc.root
80
+ @namespaces.each do |prefix, namespace|
81
+ @doc.root.add_namespace(prefix, namespace)
82
+ end
83
+ end
54
84
 
55
- # Initialize object
56
- #
57
- # @api private
58
- def initialize
59
- @doc = ::Nokogiri::XML::Document.new
85
+ @doc
60
86
  end
61
87
 
62
88
  # Create Nokogiri element
@@ -70,6 +96,16 @@ module Shale
70
96
  ::Nokogiri::XML::Element.new(name, @doc)
71
97
  end
72
98
 
99
+ # Add XML namespace to document
100
+ #
101
+ # @param [String] prefix
102
+ # @param [String] namespace
103
+ #
104
+ # @api private
105
+ def add_namespace(prefix, namespace)
106
+ @namespaces[prefix] = namespace if prefix && namespace
107
+ end
108
+
73
109
  # Add attribute to Nokogiri element
74
110
  #
75
111
  # @param [::Nokogiri::XML::Element] element Nokogiri element
@@ -115,7 +151,7 @@ module Shale
115
151
  @node = node
116
152
  end
117
153
 
118
- # Return fully qualified name of the node in the format of
154
+ # Return name of the node in the format of
119
155
  # namespace:name when the node is namespaced or just name when it's not
120
156
  #
121
157
  # @return [String]
@@ -124,11 +160,11 @@ module Shale
124
160
  # node.name # => Bar
125
161
  #
126
162
  # @example with namespace
127
- # node.name # => foo:Bar
163
+ # node.name # => http://foo:Bar
128
164
  #
129
165
  # @api private
130
166
  def name
131
- [@node.namespace&.prefix, @node.name].compact.join(':')
167
+ [@node.namespace&.href, @node.name].compact.join(':')
132
168
  end
133
169
 
134
170
  # Return all attributes associated with the node
@@ -138,7 +174,7 @@ module Shale
138
174
  # @api private
139
175
  def attributes
140
176
  @node.attribute_nodes.each_with_object({}) do |node, hash|
141
- name = [node.namespace&.prefix, node.name].compact.join(':')
177
+ name = [node.namespace&.href, node.name].compact.join(':')
142
178
  hash[name] = node.value
143
179
  end
144
180
  end
@@ -22,12 +22,24 @@ module Shale
22
22
  # Serialize Ox document into XML
23
23
  #
24
24
  # @param [::Ox::Document, ::Ox::Element] doc Ox document
25
+ # @param [Array<Symbol>] options
25
26
  #
26
27
  # @return [String]
27
28
  #
28
29
  # @api private
29
- def self.dump(doc)
30
- ::Ox.dump(doc)
30
+ def self.dump(doc, *options)
31
+ opts = { indent: -1, with_xml: false }
32
+
33
+ if options.include?(:pretty)
34
+ opts[:indent] = 2
35
+ end
36
+
37
+ if options.include?(:declaration)
38
+ doc[:version] = '1.0'
39
+ opts[:with_xml] = true
40
+ end
41
+
42
+ ::Ox.dump(doc, opts).sub(/\A\n/, '')
31
43
  end
32
44
 
33
45
  # Create Shale::Adapter::Ox::Document instance
@@ -66,6 +78,18 @@ module Shale
66
78
  ::Ox::Element.new(name)
67
79
  end
68
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
+
69
93
  # Add attribute to Ox element
70
94
  #
71
95
  # @param [::Ox::Element] element Ox element
@@ -111,8 +135,8 @@ module Shale
111
135
  @node = node
112
136
  end
113
137
 
114
- # Return fully qualified name of the node in the format of
115
- # namespace:name when the node is namespaced or just name when it's not
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
116
140
  #
117
141
  # @return [String]
118
142
  #
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rexml/document'
4
+ require_relative '../utils'
4
5
 
5
6
  module Shale
6
7
  module Adapter
@@ -23,12 +24,27 @@ module Shale
23
24
  # Serialize REXML document into XML
24
25
  #
25
26
  # @param [::REXML::Document] doc REXML document
27
+ # @param [Array<Symbol>] options
26
28
  #
27
29
  # @return [String]
28
30
  #
29
31
  # @api private
30
- def self.dump(doc)
31
- doc.to_s
32
+ def self.dump(doc, *options)
33
+ if options.include?(:declaration)
34
+ doc.add(::REXML::XMLDecl.new)
35
+ end
36
+
37
+ io = StringIO.new
38
+
39
+ if options.include?(:pretty)
40
+ formatter = ::REXML::Formatters::Pretty.new
41
+ formatter.compact = true
42
+ else
43
+ formatter = ::REXML::Formatters::Default.new
44
+ end
45
+
46
+ formatter.write(doc, io)
47
+ io.string
32
48
  end
33
49
 
34
50
  # Create Shale::Adapter::REXML::Document instance
@@ -42,18 +58,28 @@ module Shale
42
58
  #
43
59
  # @api private
44
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
+
45
70
  # Return REXML document
46
71
  #
47
72
  # @return [::REXML::Document]
48
73
  #
49
74
  # @api private
50
- attr_reader :doc
75
+ def doc
76
+ if @doc.root
77
+ @namespaces.each do |prefix, namespace|
78
+ @doc.root.add_namespace(prefix, namespace)
79
+ end
80
+ end
51
81
 
52
- # Initialize object
53
- #
54
- # @api private
55
- def initialize
56
- @doc = ::REXML::Document.new
82
+ @doc
57
83
  end
58
84
 
59
85
  # Create REXML element
@@ -64,7 +90,17 @@ module Shale
64
90
  #
65
91
  # @api private
66
92
  def create_element(name)
67
- ::REXML::Element.new(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
68
104
  end
69
105
 
70
106
  # Add attribute to REXML element
@@ -112,7 +148,7 @@ module Shale
112
148
  @node = node
113
149
  end
114
150
 
115
- # Return fully qualified name of the node in the format of
151
+ # Return name of the node in the format of
116
152
  # namespace:name when the node is namespaced or just name when it's not
117
153
  #
118
154
  # @return [String]
@@ -121,11 +157,11 @@ module Shale
121
157
  # node.name # => Bar
122
158
  #
123
159
  # @example with namespace
124
- # node.name # => foo:Bar
160
+ # node.name # => http://foo:Bar
125
161
  #
126
162
  # @api private
127
163
  def name
128
- @node.expanded_name
164
+ [Utils.presence(@node.namespace), @node.name].compact.join(':')
129
165
  end
130
166
 
131
167
  # Return all attributes associated with the node
@@ -134,7 +170,14 @@ module Shale
134
170
  #
135
171
  # @api private
136
172
  def attributes
137
- @node.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
138
181
  end
139
182
 
140
183
  # Return node's element children
@@ -20,16 +20,22 @@ module Shale
20
20
  # @api private
21
21
  attr_reader :default
22
22
 
23
+ # Return setter name
24
+ #
25
+ # @api private
26
+ attr_reader :setter
27
+
23
28
  # Initialize Attribute object
24
29
  #
25
30
  # @param [Symbol] name Name of the attribute
26
- # @param [Shale::Type::Base] type Type of the attribute
31
+ # @param [Shale::Type::Value] type Type of the attribute
27
32
  # @param [Boolean] collection Is this attribute a collection
28
33
  # @param [Proc] default Default value
29
34
  #
30
35
  # @api private
31
36
  def initialize(name, type, collection, default)
32
37
  @name = name
38
+ @setter = "#{name}="
33
39
  @type = type
34
40
  @collection = collection
35
41
  @default = collection ? -> { [] } : default
data/lib/shale/error.rb CHANGED
@@ -36,4 +36,16 @@ module Shale
36
36
  # @api private
37
37
  class IncorrectMappingArgumentsError < StandardError
38
38
  end
39
+
40
+ # Error for passing incorrect arguments to schema generation function
41
+ #
42
+ # @api private
43
+ class NotAShaleMapperError < StandardError
44
+ end
45
+
46
+ # JSON Schema compilation error
47
+ #
48
+ # @api private
49
+ class JSONSchemaError < StandardError
50
+ end
39
51
  end
data/lib/shale/mapper.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require_relative 'attribute'
4
4
  require_relative 'error'
5
5
  require_relative 'utils'
6
- require_relative 'mapping/key_value'
6
+ require_relative 'mapping/dict'
7
7
  require_relative 'mapping/xml'
8
8
  require_relative 'type/composite'
9
9
 
@@ -44,9 +44,9 @@ module Shale
44
44
  # @api public
45
45
  class Mapper < Type::Composite
46
46
  @attributes = {}
47
- @hash_mapping = Mapping::KeyValue.new
48
- @json_mapping = Mapping::KeyValue.new
49
- @yaml_mapping = Mapping::KeyValue.new
47
+ @hash_mapping = Mapping::Dict.new
48
+ @json_mapping = Mapping::Dict.new
49
+ @yaml_mapping = Mapping::Dict.new
50
50
  @xml_mapping = Mapping::Xml.new
51
51
 
52
52
  class << self
@@ -59,21 +59,21 @@ module Shale
59
59
 
60
60
  # Return Hash mapping object
61
61
  #
62
- # @return [Shale::Mapping::KeyValue]
62
+ # @return [Shale::Mapping::Dict]
63
63
  #
64
64
  # @api public
65
65
  attr_reader :hash_mapping
66
66
 
67
67
  # Return JSON mapping object
68
68
  #
69
- # @return [Shale::Mapping::KeyValue]
69
+ # @return [Shale::Mapping::Dict]
70
70
  #
71
71
  # @api public
72
72
  attr_reader :json_mapping
73
73
 
74
74
  # Return YAML mapping object
75
75
  #
76
- # @return [Shale::Mapping::KeyValue]
76
+ # @return [Shale::Mapping::Dict]
77
77
  #
78
78
  # @api public
79
79
  attr_reader :yaml_mapping
@@ -108,7 +108,7 @@ module Shale
108
108
  # Define attribute on class
109
109
  #
110
110
  # @param [Symbol] name Name of the attribute
111
- # @param [Shale::Type::Base] type Type of the attribute
111
+ # @param [Shale::Type::Value] type Type of the attribute
112
112
  # @param [Boolean] collection Is the attribute a collection
113
113
  # @param [Proc] default Default value for the attribute
114
114
  #
@@ -167,7 +167,7 @@ module Shale
167
167
  # attribute :last_name, Shale::Type::String
168
168
  # attribute :age, Shale::Type::Integer
169
169
  #
170
- # yaml do
170
+ # hsh do
171
171
  # map 'firatName', to: :first_name
172
172
  # map 'lastName', to: :last_name
173
173
  # map 'age', to: :age
@@ -175,7 +175,7 @@ module Shale
175
175
  # end
176
176
  #
177
177
  # @api public
178
- def hash(&block)
178
+ def hsh(&block)
179
179
  @hash_mapping = @__hash_mapping_init.dup
180
180
  @hash_mapping.instance_eval(&block)
181
181
  end
@@ -190,7 +190,7 @@ module Shale
190
190
  # attribute :last_name, Shale::Type::String
191
191
  # attribute :age, Shale::Type::Integer
192
192
  #
193
- # yaml do
193
+ # json do
194
194
  # map 'firatName', to: :first_name
195
195
  # map 'lastName', to: :last_name
196
196
  # map 'age', to: :age
@@ -272,9 +272,11 @@ module Shale
272
272
  def initialize(**props)
273
273
  super()
274
274
 
275
- props.each_key do |name|
276
- unless self.class.attributes.keys.include?(name)
277
- raise UnknownAttributeError.new(self.class.to_s, name.to_s)
275
+ unless props.empty?
276
+ unknown_attributes = props.keys - self.class.attributes.keys
277
+
278
+ unless unknown_attributes.empty?
279
+ raise UnknownAttributeError.new(self.class.to_s, unknown_attributes[0].to_s)
278
280
  end
279
281
  end
280
282
 
@@ -285,7 +287,7 @@ module Shale
285
287
  value = attribute.default.call
286
288
  end
287
289
 
288
- public_send("#{name}=", value)
290
+ send(attribute.setter, value)
289
291
  end
290
292
  end
291
293
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shale
4
+ module Mapping
5
+ module Descriptor
6
+ # Class representing attribute mapping
7
+ #
8
+ # @api private
9
+ class Dict
10
+ # Return mapping name
11
+ #
12
+ # @return [String]
13
+ #
14
+ # @api private
15
+ attr_reader :name
16
+
17
+ # Return attribute name
18
+ #
19
+ # @return [Symbol]
20
+ #
21
+ # @api private
22
+ attr_reader :attribute
23
+
24
+ # Return method symbol
25
+ #
26
+ # @return [Symbol]
27
+ #
28
+ # @api private
29
+ attr_reader :method_from
30
+
31
+ # Return method symbol
32
+ #
33
+ # @return [Symbol]
34
+ #
35
+ # @api private
36
+ attr_reader :method_to
37
+
38
+ # Initialize instance
39
+ #
40
+ # @param [String] name
41
+ # @param [Symbol, nil] attribute
42
+ # @param [Hash, nil] methods
43
+ #
44
+ # @api private
45
+ def initialize(name:, attribute:, methods:)
46
+ @name = name
47
+ @attribute = attribute
48
+
49
+ if methods
50
+ @method_from = methods[:from]
51
+ @method_to = methods[:to]
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dict'
4
+
5
+ module Shale
6
+ module Mapping
7
+ module Descriptor
8
+ # Class representing XML attribute mapping
9
+ #
10
+ # @api private
11
+ class Xml < Dict
12
+ # Return namespace
13
+ #
14
+ # @return [String]
15
+ #
16
+ # @api private
17
+ attr_reader :namespace
18
+
19
+ # Initialize instance
20
+ #
21
+ # @param [String] name
22
+ # @param [Symbol, String] attribute
23
+ # @param [Hash, nil] methods
24
+ # @param [Shale::Mapping::XmlNamespace] namespace
25
+ #
26
+ # @api private
27
+ def initialize(name:, attribute:, methods:, namespace:)
28
+ super(name: name, attribute: attribute, methods: methods)
29
+ @namespace = namespace
30
+ end
31
+
32
+ # Return name with XML prefix
33
+ #
34
+ # @return [String]
35
+ #
36
+ # @api private
37
+ def prefixed_name
38
+ [namespace.prefix, name].compact.join(':')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shale
4
+ module Mapping
5
+ module Descriptor
6
+ # Class representing XML namespace
7
+ #
8
+ # @api private
9
+ class XmlNamespace
10
+ # Return name
11
+ #
12
+ # @return [String]
13
+ #
14
+ # @api private
15
+ attr_accessor :name
16
+
17
+ # Return prefix
18
+ #
19
+ # @return [String]
20
+ #
21
+ # @api private
22
+ attr_accessor :prefix
23
+
24
+ # Initialize instance
25
+ #
26
+ # @param [String, nil] name
27
+ # @param [String, nil] prefix
28
+ #
29
+ # @api private
30
+ def initialize(name = nil, prefix = nil)
31
+ @name = name
32
+ @prefix = prefix
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
3
+ require_relative 'descriptor/dict'
4
+ require_relative 'validator'
4
5
 
5
6
  module Shale
6
7
  module Mapping
7
- # Mapping for key/value serialization formats (Hash/JSON/YAML)
8
+ # Mapping for dictionary serialization formats (Hash/JSON/YAML)
8
9
  #
9
10
  # @api private
10
- class KeyValue < Base
11
+ class Dict
11
12
  # Return keys mapping hash
12
13
  #
13
14
  # @return [Hash]
@@ -26,14 +27,15 @@ module Shale
26
27
  # Map key to attribute
27
28
  #
28
29
  # @param [String] key Document's key
29
- # @param [Symbol] to Object's attribute
30
+ # @param [Symbol, nil] to Object's attribute
31
+ # @param [Hash, nil] using
30
32
  #
31
33
  # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
32
34
  #
33
35
  # @api private
34
36
  def map(key, to: nil, using: nil)
35
- validate_arguments(key, to, using)
36
- @keys[key] = to || using
37
+ Validator.validate_arguments(key, to, using)
38
+ @keys[key] = Descriptor::Dict.new(name: key, attribute: to, methods: using)
37
39
  end
38
40
 
39
41
  # @api private
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../error'
4
+
5
+ module Shale
6
+ module Mapping
7
+ module Validator
8
+ # Validate correctness of argument passed to map functions
9
+ #
10
+ # @param [String] key
11
+ # @param [Symbol] to
12
+ # @param [Hash] using
13
+ #
14
+ # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
15
+ #
16
+ # @api private
17
+ def self.validate_arguments(key, to, using)
18
+ if to.nil? && using.nil?
19
+ msg = ":to or :using argument is required for mapping '#{key}'"
20
+ raise IncorrectMappingArgumentsError, msg
21
+ end
22
+
23
+ if !using.nil? && (using[:from].nil? || using[:to].nil?)
24
+ msg = ":using argument for mapping '#{key}' requires :to and :from keys"
25
+ raise IncorrectMappingArgumentsError, msg
26
+ end
27
+ end
28
+
29
+ # Validate correctness of namespace arguments
30
+ #
31
+ # @param [String] key
32
+ # @param [String, Symbol, nil] namespace
33
+ # @param [String, Symbol, nil] prefix
34
+ #
35
+ # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
36
+ #
37
+ # @api private
38
+ def self.validate_namespace(key, namespace, prefix)
39
+ return if namespace == :undefined && prefix == :undefined
40
+
41
+ nsp = namespace == :undefined ? nil : namespace
42
+ pfx = prefix == :undefined ? nil : prefix
43
+
44
+ if (nsp && !pfx) || (!nsp && pfx)
45
+ msg = "both :namespace and :prefix arguments are required for mapping '#{key}'"
46
+ raise IncorrectMappingArgumentsError, msg
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end