shale 0.7.1 → 0.9.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 +19 -2
- data/README.md +184 -15
- 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/mapper.rb +40 -1
- data/lib/shale/mapping/descriptor/dict.rb +10 -1
- data/lib/shale/mapping/descriptor/xml.rb +19 -2
- data/lib/shale/mapping/dict.rb +14 -46
- data/lib/shale/mapping/dict_base.rb +76 -0
- data/lib/shale/mapping/dict_group.rb +41 -0
- data/lib/shale/mapping/group/dict.rb +55 -0
- data/lib/shale/mapping/group/dict_grouping.rb +41 -0
- data/lib/shale/mapping/group/xml.rb +43 -0
- data/lib/shale/mapping/group/xml_grouping.rb +27 -0
- data/lib/shale/mapping/xml.rb +40 -152
- data/lib/shale/mapping/xml_base.rb +227 -0
- data/lib/shale/mapping/xml_group.rb +70 -0
- data/lib/shale/type/complex.rb +198 -18
- 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/version.rb +1 -1
- data/lib/shale.rb +30 -4
- data/shale.gemspec +3 -3
- metadata +14 -5
data/lib/shale/mapping/dict.rb
CHANGED
@@ -1,71 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
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
|
33
|
-
# @param [true, false] render_nil
|
17
|
+
# @param [true, false, nil] render_nil
|
34
18
|
#
|
35
19
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
36
20
|
#
|
37
21
|
# @api private
|
38
|
-
def map(key, to: nil, using: nil, render_nil:
|
39
|
-
|
40
|
-
@keys[key] = Descriptor::Dict.new(
|
41
|
-
name: key,
|
42
|
-
attribute: to,
|
43
|
-
methods: using,
|
44
|
-
render_nil: render_nil
|
45
|
-
)
|
22
|
+
def map(key, to: nil, using: nil, render_nil: nil)
|
23
|
+
super(key, to: to, using: using, render_nil: render_nil)
|
46
24
|
end
|
47
25
|
|
48
|
-
#
|
26
|
+
# Map group of keys to mapping methods
|
49
27
|
#
|
50
|
-
# @
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
# Query the "finalized" instance variable
|
56
|
-
#
|
57
|
-
# @return [truem false]
|
28
|
+
# @param [Symbol] from
|
29
|
+
# @param [Symbol] to
|
30
|
+
# @param [Proc] block
|
58
31
|
#
|
59
32
|
# @api private
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# @api private
|
65
|
-
def initialize_dup(other)
|
66
|
-
@keys = other.instance_variable_get('@keys').dup
|
67
|
-
@finalized = false
|
68
|
-
super
|
33
|
+
def group(from:, to:, &block)
|
34
|
+
group = DictGroup.new(from, to)
|
35
|
+
group.instance_eval(&block)
|
36
|
+
@keys.merge!(group.keys)
|
69
37
|
end
|
70
38
|
end
|
71
39
|
end
|
@@ -0,0 +1,76 @@
|
|
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
|
+
# @param [true, false] render_nil_default
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
def initialize(render_nil_default: false)
|
25
|
+
@keys = {}
|
26
|
+
@finalized = false
|
27
|
+
@render_nil_default = render_nil_default
|
28
|
+
end
|
29
|
+
|
30
|
+
# Map key to attribute
|
31
|
+
#
|
32
|
+
# @param [String] key
|
33
|
+
# @param [Symbol, nil] to
|
34
|
+
# @param [Hash, nil] using
|
35
|
+
# @param [String, nil] group
|
36
|
+
# @param [true, false, nil] render_nil
|
37
|
+
#
|
38
|
+
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def map(key, to: nil, using: nil, group: nil, render_nil: nil)
|
42
|
+
Validator.validate_arguments(key, to, using)
|
43
|
+
@keys[key] = Descriptor::Dict.new(
|
44
|
+
name: key,
|
45
|
+
attribute: to,
|
46
|
+
methods: using,
|
47
|
+
group: group,
|
48
|
+
render_nil: render_nil.nil? ? @render_nil_default : render_nil
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set the "finalized" instance variable to true
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def finalize!
|
56
|
+
@finalized = true
|
57
|
+
end
|
58
|
+
|
59
|
+
# Query the "finalized" instance variable
|
60
|
+
#
|
61
|
+
# @return [truem false]
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def finalized?
|
65
|
+
@finalized
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def initialize_dup(other)
|
70
|
+
@keys = other.instance_variable_get('@keys').dup
|
71
|
+
@finalized = false
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
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
|
data/lib/shale/mapping/xml.rb
CHANGED
@@ -1,80 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
72
|
-
# @param [Symbol, nil] to
|
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
|
-
# @
|
19
|
+
# @param [true, false] cdata
|
20
|
+
# @param [true, false] render_nil
|
78
21
|
#
|
79
22
|
# @api private
|
80
23
|
def map_element(
|
@@ -86,24 +29,12 @@ module Shale
|
|
86
29
|
cdata: false,
|
87
30
|
render_nil: false
|
88
31
|
)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
else
|
96
|
-
nsp = namespace
|
97
|
-
pfx = prefix
|
98
|
-
end
|
99
|
-
|
100
|
-
namespaced_element = [nsp, element].compact.join(':')
|
101
|
-
|
102
|
-
@elements[namespaced_element] = Descriptor::Xml.new(
|
103
|
-
name: element,
|
104
|
-
attribute: to,
|
105
|
-
methods: using,
|
106
|
-
namespace: Descriptor::XmlNamespace.new(nsp, pfx),
|
32
|
+
super(
|
33
|
+
element,
|
34
|
+
to: to,
|
35
|
+
using: using,
|
36
|
+
namespace: namespace,
|
37
|
+
prefix: prefix,
|
107
38
|
cdata: cdata,
|
108
39
|
render_nil: render_nil
|
109
40
|
)
|
@@ -111,13 +42,12 @@ module Shale
|
|
111
42
|
|
112
43
|
# Map document's attribute to object's attribute
|
113
44
|
#
|
114
|
-
# @param [String] attribute
|
115
|
-
# @param [Symbol, nil] to
|
45
|
+
# @param [String] attribute
|
46
|
+
# @param [Symbol, nil] to
|
116
47
|
# @param [Hash, nil] using
|
117
48
|
# @param [String, nil] namespace
|
118
49
|
# @param [String, nil] prefix
|
119
|
-
#
|
120
|
-
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
50
|
+
# @param [true, false] render_nil
|
121
51
|
#
|
122
52
|
# @api private
|
123
53
|
def map_attribute(
|
@@ -128,85 +58,43 @@ module Shale
|
|
128
58
|
prefix: nil,
|
129
59
|
render_nil: false
|
130
60
|
)
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
name: attribute,
|
138
|
-
attribute: to,
|
139
|
-
methods: using,
|
140
|
-
namespace: Descriptor::XmlNamespace.new(namespace, prefix),
|
141
|
-
cdata: false,
|
61
|
+
super(
|
62
|
+
attribute,
|
63
|
+
to: to,
|
64
|
+
using: using,
|
65
|
+
namespace: namespace,
|
66
|
+
prefix: prefix,
|
142
67
|
render_nil: render_nil
|
143
68
|
)
|
144
69
|
end
|
145
70
|
|
146
71
|
# Map document's content to object's attribute
|
147
72
|
#
|
148
|
-
# @param [Symbol] to
|
73
|
+
# @param [Symbol] to
|
74
|
+
# @param [Hash, nil] using
|
75
|
+
# @param [true, false] cdata
|
149
76
|
#
|
150
77
|
# @api private
|
151
78
|
def map_content(to: nil, using: nil, cdata: false)
|
152
|
-
|
153
|
-
|
154
|
-
@content = Descriptor::Xml.new(
|
155
|
-
name: nil,
|
156
|
-
attribute: to,
|
157
|
-
methods: using,
|
158
|
-
namespace: nil,
|
159
|
-
cdata: cdata,
|
160
|
-
render_nil: false
|
161
|
-
)
|
162
|
-
end
|
163
|
-
|
164
|
-
# Set the name for root element
|
165
|
-
#
|
166
|
-
# @param [String] value root's name
|
167
|
-
#
|
168
|
-
# @api private
|
169
|
-
def root(value)
|
170
|
-
@root = value
|
171
|
-
end
|
172
|
-
|
173
|
-
# Set default namespace for root element
|
174
|
-
#
|
175
|
-
# @param [String] name
|
176
|
-
# @param [String] prefix
|
177
|
-
#
|
178
|
-
# @api private
|
179
|
-
def namespace(name, prefix)
|
180
|
-
@default_namespace.name = name
|
181
|
-
@default_namespace.prefix = prefix
|
79
|
+
super(to: to, using: using, cdata: cdata)
|
182
80
|
end
|
183
81
|
|
184
|
-
#
|
82
|
+
# Map group of nodes to mapping methods
|
185
83
|
#
|
186
|
-
# @
|
187
|
-
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
# Query the "finalized" instance variable
|
192
|
-
#
|
193
|
-
# @return [truem false]
|
84
|
+
# @param [Symbol] from
|
85
|
+
# @param [Symbol] to
|
86
|
+
# @param [Proc] block
|
194
87
|
#
|
195
88
|
# @api private
|
196
|
-
def
|
197
|
-
|
198
|
-
end
|
89
|
+
def group(from:, to:, &block)
|
90
|
+
group = XmlGroup.new(from, to)
|
199
91
|
|
200
|
-
|
201
|
-
|
202
|
-
@elements = other.instance_variable_get('@elements').dup
|
203
|
-
@attributes = other.instance_variable_get('@attributes').dup
|
204
|
-
@content = other.instance_variable_get('@content').dup
|
205
|
-
@root = other.instance_variable_get('@root').dup
|
206
|
-
@default_namespace = other.instance_variable_get('@default_namespace').dup
|
207
|
-
@finalized = false
|
92
|
+
group.namespace(default_namespace.name, default_namespace.prefix)
|
93
|
+
group.instance_eval(&block)
|
208
94
|
|
209
|
-
|
95
|
+
@elements.merge!(group.elements)
|
96
|
+
@attributes.merge!(group.attributes)
|
97
|
+
@content = group.content if group.content
|
210
98
|
end
|
211
99
|
end
|
212
100
|
end
|