shale 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,65 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'descriptor/dict'
4
- require_relative 'validator'
3
+ require_relative 'dict_base'
4
+ require_relative 'dict_group'
5
5
 
6
6
  module Shale
7
7
  module Mapping
8
8
  # Mapping for dictionary serialization formats (Hash/JSON/YAML)
9
9
  #
10
10
  # @api private
11
- class Dict
12
- # Return keys mapping hash
13
- #
14
- # @return [Hash]
15
- #
16
- # @api private
17
- attr_reader :keys
18
-
19
- # Initialize instance
20
- #
21
- # @api private
22
- def initialize
23
- super
24
- @keys = {}
25
- @finalized = false
26
- end
27
-
11
+ class Dict < DictBase
28
12
  # Map key to attribute
29
13
  #
30
14
  # @param [String] key Document's key
31
15
  # @param [Symbol, nil] to Object's attribute
32
16
  # @param [Hash, nil] using
17
+ # @param [true, false] render_nil
33
18
  #
34
19
  # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
35
20
  #
36
21
  # @api private
37
- def map(key, to: nil, using: nil)
38
- Validator.validate_arguments(key, to, using)
39
- @keys[key] = Descriptor::Dict.new(name: key, attribute: to, methods: using)
22
+ def map(key, to: nil, using: nil, render_nil: false)
23
+ super(key, to: to, using: using, render_nil: render_nil)
40
24
  end
41
25
 
42
- # Set the "finalized" instance variable to true
26
+ # Map group of keys to mapping methods
43
27
  #
44
- # @api private
45
- def finalize!
46
- @finalized = true
47
- end
48
-
49
- # Query the "finalized" instance variable
50
- #
51
- # @return [truem false]
28
+ # @param [Symbol] from
29
+ # @param [Symbol] to
30
+ # @param [Proc] block
52
31
  #
53
32
  # @api private
54
- def finalized?
55
- @finalized
56
- end
57
-
58
- # @api private
59
- def initialize_dup(other)
60
- @keys = other.instance_variable_get('@keys').dup
61
- @finalized = false
62
- super
33
+ def group(from:, to:, &block)
34
+ group = DictGroup.new(from, to)
35
+ group.instance_eval(&block)
36
+ @keys.merge!(group.keys)
63
37
  end
64
38
  end
65
39
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'descriptor/dict'
4
+ require_relative 'validator'
5
+
6
+ module Shale
7
+ module Mapping
8
+ # Base class for Mapping dictionary serialization formats (Hash/JSON/YAML)
9
+ #
10
+ # @api private
11
+ class DictBase
12
+ # Return keys mapping hash
13
+ #
14
+ # @return [Hash]
15
+ #
16
+ # @api private
17
+ attr_reader :keys
18
+
19
+ # Initialize instance
20
+ #
21
+ # @api private
22
+ def initialize
23
+ @keys = {}
24
+ @finalized = false
25
+ end
26
+
27
+ # Map key to attribute
28
+ #
29
+ # @param [String] key
30
+ # @param [Symbol, nil] to
31
+ # @param [Hash, nil] using
32
+ # @param [String, nil] group
33
+ # @param [true, false] render_nil
34
+ #
35
+ # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
36
+ #
37
+ # @api private
38
+ def map(key, to: nil, using: nil, group: nil, render_nil: false)
39
+ Validator.validate_arguments(key, to, using)
40
+ @keys[key] = Descriptor::Dict.new(
41
+ name: key,
42
+ attribute: to,
43
+ methods: using,
44
+ group: group,
45
+ render_nil: render_nil
46
+ )
47
+ end
48
+
49
+ # Set the "finalized" instance variable to true
50
+ #
51
+ # @api private
52
+ def finalize!
53
+ @finalized = true
54
+ end
55
+
56
+ # Query the "finalized" instance variable
57
+ #
58
+ # @return [truem false]
59
+ #
60
+ # @api private
61
+ def finalized?
62
+ @finalized
63
+ end
64
+
65
+ # @api private
66
+ def initialize_dup(other)
67
+ @keys = other.instance_variable_get('@keys').dup
68
+ @finalized = false
69
+ super
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dict_base'
4
+
5
+ module Shale
6
+ module Mapping
7
+ # Group for dictionary serialization formats (Hash/JSON/YAML)
8
+ #
9
+ # @api private
10
+ class DictGroup < DictBase
11
+ # Return name of the group
12
+ #
13
+ # @return [String]
14
+ #
15
+ # @api private
16
+ attr_reader :name
17
+
18
+ # Initialize instance
19
+ #
20
+ # @param [Symbol] from
21
+ # @param [Symbol] to
22
+ #
23
+ # @api private
24
+ def initialize(from, to)
25
+ super()
26
+ @from = from
27
+ @to = to
28
+ @name = "group_#{hash}"
29
+ end
30
+
31
+ # Map key to attribute
32
+ #
33
+ # @param [String] key
34
+ #
35
+ # @api private
36
+ def map(key)
37
+ super(key, using: { from: @from, to: @to }, group: @name)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shale
4
+ module Mapping
5
+ module Group
6
+ # Dict group descriptor
7
+ #
8
+ # @api private
9
+ class Dict
10
+ # Return method_from
11
+ #
12
+ # @return [Symbol]
13
+ #
14
+ # @api private
15
+ attr_reader :method_from
16
+
17
+ # Return method_to
18
+ #
19
+ # @return [Symbol]
20
+ #
21
+ # @api private
22
+ attr_reader :method_to
23
+
24
+ # Return dict hash
25
+ #
26
+ # @return [Hash]
27
+ #
28
+ # @api private
29
+ attr_reader :dict
30
+
31
+ # Initialize instance
32
+ #
33
+ # @param [Symbol] method_from
34
+ # @param [Symbol] method_to
35
+ #
36
+ # @api private
37
+ def initialize(method_from, method_to)
38
+ @method_from = method_from
39
+ @method_to = method_to
40
+ @dict = {}
41
+ end
42
+
43
+ # Add key-value pair to a group
44
+ #
45
+ # @param [String] key
46
+ # @param [any] value
47
+ #
48
+ # @api private
49
+ def add(key, value)
50
+ @dict[key] = value
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dict'
4
+
5
+ module Shale
6
+ module Mapping
7
+ module Group
8
+ # Class representing mapping group for JSON/YAML/TOML
9
+ #
10
+ # @api private
11
+ class DictGrouping
12
+ # Initialize instance
13
+ #
14
+ # @api private
15
+ def initialize
16
+ @groups = {}
17
+ end
18
+
19
+ # Add a value to a group
20
+ #
21
+ # @param [Shale::Mapping::Descriptor::Dict] mapping
22
+ # @param [any] value
23
+ #
24
+ # @api private
25
+ def add(mapping, value)
26
+ group = @groups[mapping.group] ||= Dict.new(mapping.method_from, mapping.method_to)
27
+ group.add(mapping.name, value)
28
+ end
29
+
30
+ # Iterate over groups
31
+ #
32
+ # @param [Proc] block
33
+ #
34
+ # @api private
35
+ def each(&block)
36
+ @groups.values.each(&block)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dict'
4
+
5
+ module Shale
6
+ module Mapping
7
+ module Group
8
+ # Xml group descriptor
9
+ #
10
+ # @api private
11
+ class Xml < Dict
12
+ # Initialize instance
13
+ #
14
+ # @param [Symbol] method_from
15
+ # @param [Symbol] method_to
16
+ #
17
+ # @api private
18
+ def initialize(method_from, method_to)
19
+ super(method_from, method_to)
20
+ @dict = { content: nil, attributes: {}, elements: {} }
21
+ end
22
+
23
+ # Add key-value pair to a group
24
+ #
25
+ # @param [Symbol] kind
26
+ # @param [String] key
27
+ # @param [any] value
28
+ #
29
+ # @api private
30
+ def add(kind, key, value)
31
+ case kind
32
+ when :content
33
+ @dict[:content] = value
34
+ when :attribute
35
+ @dict[:attributes][key] = value
36
+ when :element
37
+ @dict[:elements][key] = value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dict_grouping'
4
+ require_relative 'xml'
5
+
6
+ module Shale
7
+ module Mapping
8
+ module Group
9
+ # Class representing mapping group for XML
10
+ #
11
+ # @api private
12
+ class XmlGrouping < DictGrouping
13
+ # Add a value to a group
14
+ #
15
+ # @param [Shale::Mapping::Descriptor::Dict] mapping
16
+ # @param [Symbol] kind
17
+ # @param [any] value
18
+ #
19
+ # @api private
20
+ def add(mapping, kind, value)
21
+ group = @groups[mapping.group] ||= Xml.new(mapping.method_from, mapping.method_to)
22
+ group.add(kind, mapping.namespaced_name, value)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,80 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'descriptor/xml'
4
- require_relative 'descriptor/xml_namespace'
5
- require_relative 'validator'
3
+ require_relative 'xml_base'
4
+ require_relative 'xml_group'
6
5
 
7
6
  module Shale
8
7
  module Mapping
9
- class Xml
10
- # Return elements mapping hash
11
- #
12
- # @return [Hash]
13
- #
14
- # @api private
15
- attr_reader :elements
16
-
17
- # Return attributes mapping hash
18
- #
19
- # @return [Hash]
20
- #
21
- # @api private
22
- attr_reader :attributes
23
-
24
- # Return content mapping
25
- #
26
- # @return [Symbol]
27
- #
28
- # @api private
29
- attr_reader :content
30
-
31
- # Return default namespace
32
- #
33
- # @return [Shale::Mapping::Descriptor::XmlNamespace]
34
- #
35
- # @api private
36
- attr_reader :default_namespace
37
-
38
- # Return unprefixed root
39
- #
40
- # @return [String]
41
- #
42
- # @api private
43
- def unprefixed_root
44
- @root
45
- end
46
-
47
- # Return prefixed root
48
- #
49
- # @return [String]
50
- #
51
- # @api private
52
- def prefixed_root
53
- [default_namespace.prefix, @root].compact.join(':')
54
- end
55
-
56
- # Initialize instance
57
- #
58
- # @api private
59
- def initialize
60
- super
61
- @elements = {}
62
- @attributes = {}
63
- @content = nil
64
- @root = ''
65
- @default_namespace = Descriptor::XmlNamespace.new
66
- @finalized = false
67
- end
68
-
8
+ # Mapping for XML serialization format
9
+ #
10
+ # @api private
11
+ class Xml < XmlBase
69
12
  # Map element to attribute
70
13
  #
71
- # @param [String] element Document's element
72
- # @param [Symbol, nil] to Object's attribute
14
+ # @param [String] element
15
+ # @param [Symbol, nil] to
73
16
  # @param [Hash, nil] using
74
17
  # @param [String, nil] namespace
75
18
  # @param [String, nil] prefix
76
- #
77
- # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
19
+ # @param [true, false] cdata
20
+ # @param [true, false] render_nil
78
21
  #
79
22
  # @api private
80
23
  def map_element(
@@ -83,119 +26,75 @@ module Shale
83
26
  using: nil,
84
27
  namespace: :undefined,
85
28
  prefix: :undefined,
86
- cdata: false
29
+ cdata: false,
30
+ render_nil: false
87
31
  )
88
- Validator.validate_arguments(element, to, using)
89
- Validator.validate_namespace(element, namespace, prefix)
90
-
91
- if namespace == :undefined && prefix == :undefined
92
- nsp = default_namespace.name
93
- pfx = default_namespace.prefix
94
- else
95
- nsp = namespace
96
- pfx = prefix
97
- end
98
-
99
- namespaced_element = [nsp, element].compact.join(':')
100
-
101
- @elements[namespaced_element] = Descriptor::Xml.new(
102
- name: element,
103
- attribute: to,
104
- methods: using,
105
- namespace: Descriptor::XmlNamespace.new(nsp, pfx),
106
- cdata: cdata
32
+ super(
33
+ element,
34
+ to: to,
35
+ using: using,
36
+ namespace: namespace,
37
+ prefix: prefix,
38
+ cdata: cdata,
39
+ render_nil: render_nil
107
40
  )
108
41
  end
109
42
 
110
43
  # Map document's attribute to object's attribute
111
44
  #
112
- # @param [String] attribute Document's attribute
113
- # @param [Symbol, nil] to Object's attribute
45
+ # @param [String] attribute
46
+ # @param [Symbol, nil] to
114
47
  # @param [Hash, nil] using
115
48
  # @param [String, nil] namespace
116
49
  # @param [String, nil] prefix
117
- #
118
- # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
50
+ # @param [true, false] render_nil
119
51
  #
120
52
  # @api private
121
- def map_attribute(attribute, to: nil, using: nil, namespace: nil, prefix: nil)
122
- Validator.validate_arguments(attribute, to, using)
123
- Validator.validate_namespace(attribute, namespace, prefix)
124
-
125
- namespaced_attribute = [namespace, attribute].compact.join(':')
126
-
127
- @attributes[namespaced_attribute] = Descriptor::Xml.new(
128
- name: attribute,
129
- attribute: to,
130
- methods: using,
131
- namespace: Descriptor::XmlNamespace.new(namespace, prefix),
132
- cdata: false
53
+ def map_attribute(
54
+ attribute,
55
+ to: nil,
56
+ using: nil,
57
+ namespace: nil,
58
+ prefix: nil,
59
+ render_nil: false
60
+ )
61
+ super(
62
+ attribute,
63
+ to: to,
64
+ using: using,
65
+ namespace: namespace,
66
+ prefix: prefix,
67
+ render_nil: render_nil
133
68
  )
134
69
  end
135
70
 
136
71
  # Map document's content to object's attribute
137
72
  #
138
- # @param [Symbol] to Object's attribute
73
+ # @param [Symbol] to
74
+ # @param [Hash, nil] using
75
+ # @param [true, false] cdata
139
76
  #
140
77
  # @api private
141
78
  def map_content(to: nil, using: nil, cdata: false)
142
- Validator.validate_arguments('content', to, using)
143
-
144
- @content = Descriptor::Xml.new(
145
- name: nil,
146
- attribute: to,
147
- methods: using,
148
- namespace: nil,
149
- cdata: cdata
150
- )
79
+ super(to: to, using: using, cdata: cdata)
151
80
  end
152
81
 
153
- # Set the name for root element
82
+ # Map group of nodes to mapping methods
154
83
  #
155
- # @param [String] value root's name
84
+ # @param [Symbol] from
85
+ # @param [Symbol] to
86
+ # @param [Proc] block
156
87
  #
157
88
  # @api private
158
- def root(value)
159
- @root = value
160
- end
89
+ def group(from:, to:, &block)
90
+ group = XmlGroup.new(from, to)
161
91
 
162
- # Set default namespace for root element
163
- #
164
- # @param [String] name
165
- # @param [String] prefix
166
- #
167
- # @api private
168
- def namespace(name, prefix)
169
- @default_namespace.name = name
170
- @default_namespace.prefix = prefix
171
- end
172
-
173
- # Set the "finalized" instance variable to true
174
- #
175
- # @api private
176
- def finalize!
177
- @finalized = true
178
- end
179
-
180
- # Query the "finalized" instance variable
181
- #
182
- # @return [truem false]
183
- #
184
- # @api private
185
- def finalized?
186
- @finalized
187
- end
188
-
189
- # @api private
190
- def initialize_dup(other)
191
- @elements = other.instance_variable_get('@elements').dup
192
- @attributes = other.instance_variable_get('@attributes').dup
193
- @content = other.instance_variable_get('@content').dup
194
- @root = other.instance_variable_get('@root').dup
195
- @default_namespace = other.instance_variable_get('@default_namespace').dup
196
- @finalized = false
92
+ group.namespace(default_namespace.name, default_namespace.prefix)
93
+ group.instance_eval(&block)
197
94
 
198
- super
95
+ @elements.merge!(group.elements)
96
+ @attributes.merge!(group.attributes)
97
+ @content = group.content if group.content
199
98
  end
200
99
  end
201
100
  end