shale 0.4.0 → 0.5.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +93 -7
  4. data/exe/shaleb +30 -6
  5. data/lib/shale/adapter/nokogiri/document.rb +87 -0
  6. data/lib/shale/adapter/nokogiri/node.rb +100 -0
  7. data/lib/shale/adapter/nokogiri.rb +11 -151
  8. data/lib/shale/adapter/ox/document.rb +80 -0
  9. data/lib/shale/adapter/ox/node.rb +88 -0
  10. data/lib/shale/adapter/ox.rb +9 -134
  11. data/lib/shale/adapter/rexml/document.rb +88 -0
  12. data/lib/shale/adapter/rexml/node.rb +99 -0
  13. data/lib/shale/adapter/rexml.rb +9 -150
  14. data/lib/shale/error.rb +35 -2
  15. data/lib/shale/mapper.rb +2 -2
  16. data/lib/shale/schema/{json_compiler → compiler}/boolean.rb +1 -1
  17. data/lib/shale/schema/{json_compiler/object.rb → compiler/complex.rb} +11 -8
  18. data/lib/shale/schema/{json_compiler → compiler}/date.rb +1 -1
  19. data/lib/shale/schema/{json_compiler → compiler}/float.rb +1 -1
  20. data/lib/shale/schema/{json_compiler → compiler}/integer.rb +1 -1
  21. data/lib/shale/schema/{json_compiler → compiler}/property.rb +6 -6
  22. data/lib/shale/schema/{json_compiler → compiler}/string.rb +1 -1
  23. data/lib/shale/schema/{json_compiler → compiler}/time.rb +1 -1
  24. data/lib/shale/schema/compiler/value.rb +21 -0
  25. data/lib/shale/schema/compiler/xml_complex.rb +50 -0
  26. data/lib/shale/schema/compiler/xml_property.rb +73 -0
  27. data/lib/shale/schema/json_compiler.rb +32 -34
  28. data/lib/shale/schema/json_generator.rb +3 -3
  29. data/lib/shale/schema/xml_compiler.rb +919 -0
  30. data/lib/shale/schema/xml_generator.rb +7 -7
  31. data/lib/shale/schema.rb +16 -0
  32. data/lib/shale/type/{composite.rb → complex.rb} +20 -2
  33. data/lib/shale/utils.rb +42 -7
  34. data/lib/shale/version.rb +1 -1
  35. data/lib/shale.rb +8 -19
  36. data/shale.gemspec +1 -1
  37. metadata +23 -15
  38. data/lib/shale/schema/json_compiler/utils.rb +0 -52
  39. data/lib/shale/schema/json_compiler/value.rb +0 -13
@@ -94,12 +94,12 @@ module Shale
94
94
  )
95
95
  schemas[default_namespace.name].add_child(root_element)
96
96
 
97
- composites = []
98
- collect_composite_types(composites, klass, klass.xml_mapping.default_namespace.name)
97
+ complexes = []
98
+ collect_complex_types(complexes, klass, klass.xml_mapping.default_namespace.name)
99
99
 
100
- composites.each do |composite|
101
- type = composite[:type]
102
- namespace = composite[:namespace]
100
+ complexes.each do |complex|
101
+ type = complex[:type]
102
+ namespace = complex[:namespace]
103
103
  children = []
104
104
 
105
105
  type.xml_mapping.elements.values.each do |mapping|
@@ -252,7 +252,7 @@ module Shale
252
252
  # @param [String, nil] namespace
253
253
  #
254
254
  # @api private
255
- def collect_composite_types(types, type, namespace)
255
+ def collect_complex_types(types, type, namespace)
256
256
  types << { type: type, namespace: namespace }
257
257
 
258
258
  type.xml_mapping.elements.values.each do |mapping|
@@ -263,7 +263,7 @@ module Shale
263
263
  is_included = types.include?({ type: attribute.type, namespace: namespace })
264
264
 
265
265
  if is_mapper && !is_included
266
- collect_composite_types(types, attribute.type, mapping.namespace.name)
266
+ collect_complex_types(types, attribute.type, mapping.namespace.name)
267
267
  end
268
268
  end
269
269
  end
data/lib/shale/schema.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require_relative 'schema/json_generator'
4
4
  require_relative 'schema/json_compiler'
5
5
  require_relative 'schema/xml_generator'
6
+ require_relative 'schema/xml_compiler'
6
7
 
7
8
  module Shale
8
9
  # Module for handling JSON and XML schema
@@ -66,5 +67,20 @@ module Shale
66
67
  def self.to_xml(klass, base_name = nil, pretty: false, declaration: false)
67
68
  XMLGenerator.new.to_schemas(klass, base_name, pretty: pretty, declaration: declaration)
68
69
  end
70
+
71
+ # Generate Shale model from XML Schema
72
+ #
73
+ # @param [Array<String>] schemas
74
+ #
75
+ # @return [Array<String>]
76
+ #
77
+ # @example
78
+ # Shale::Schema.from_xml([xml_schema1, xml_schema2])
79
+ # # => [model1, model2, model3]
80
+ #
81
+ # @api public
82
+ def self.from_xml(schemas)
83
+ XMLCompiler.new.to_models(schemas)
84
+ end
69
85
  end
70
86
  end
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../error'
3
4
  require_relative 'value'
4
5
 
5
6
  module Shale
6
7
  module Type
7
- # Build composite object. Don't use it directly.
8
+ # Build complex object. Don't use it directly.
8
9
  # It serves as a base type class for @see Shale::Mapper
9
10
  #
10
11
  # @api private
11
- class Composite < Value
12
+ class Complex < Value
12
13
  class << self
13
14
  %i[hash json yaml].each do |format|
14
15
  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
@@ -198,10 +199,13 @@ module Shale
198
199
  #
199
200
  # @param [String] xml XML to convert
200
201
  #
202
+ # @raise [AdapterError]
203
+ #
201
204
  # @return [Shale::Mapper]
202
205
  #
203
206
  # @api public
204
207
  def from_xml(xml)
208
+ validate_xml_adapter
205
209
  of_xml(Shale.xml_adapter.load(xml))
206
210
  end
207
211
 
@@ -279,12 +283,26 @@ module Shale
279
283
  # @param [Shale::Mapper] instance Object to convert
280
284
  # @param [Array<Symbol>] options
281
285
  #
286
+ # @raise [AdapterError]
287
+ #
282
288
  # @return [String]
283
289
  #
284
290
  # @api public
285
291
  def to_xml(instance, *options)
292
+ validate_xml_adapter
286
293
  Shale.xml_adapter.dump(as_xml(instance), *options)
287
294
  end
295
+
296
+ private
297
+
298
+ # Validate XML adapter
299
+ #
300
+ # @raise [AdapterError]
301
+ #
302
+ # @api private
303
+ def validate_xml_adapter
304
+ raise AdapterError, ADAPTER_NOT_SET_MESSAGE unless Shale.xml_adapter
305
+ end
288
306
  end
289
307
 
290
308
  # Convert Object to Hash
data/lib/shale/utils.rb CHANGED
@@ -5,6 +5,46 @@ module Shale
5
5
  #
6
6
  # @api private
7
7
  module Utils
8
+ # Convert string to Ruby's class naming convention
9
+ #
10
+ # @param [String] val
11
+ #
12
+ # @example
13
+ # Shale::Utils.classify('foobar')
14
+ # # => 'Foobar'
15
+ #
16
+ # @api private
17
+ def self.classify(str)
18
+ str = str.to_s.sub(/.*\./, '')
19
+
20
+ str = str.sub(/^[a-z\d]*/) { |match| match.capitalize || match }
21
+
22
+ str.gsub(%r{(?:_|-|(/))([a-z\d]*)}i) do
23
+ word = Regexp.last_match(2)
24
+ substituted = word.capitalize || word
25
+ Regexp.last_match(1) ? "::#{substituted}" : substituted
26
+ end
27
+ end
28
+
29
+ # Convert string to snake case
30
+ #
31
+ # @param [String] val
32
+ #
33
+ # @example
34
+ # Shale::Utils.snake_case('FooBar')
35
+ # # => 'foo_bar'
36
+ #
37
+ # @api private
38
+ def self.snake_case(str)
39
+ return str.to_s unless /[A-Z-]|::/.match?(str)
40
+ word = str.to_s.gsub('::', '/')
41
+ word = word.gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
42
+ "#{Regexp.last_match(1) || Regexp.last_match(2)}_"
43
+ end
44
+ word = word.tr('-', '_')
45
+ word.downcase
46
+ end
47
+
8
48
  # Convert word to under score
9
49
  #
10
50
  # @param [String] word
@@ -14,13 +54,8 @@ module Shale
14
54
  # Shale::Utils.underscore('Namespace::FooBar') # => foo_bar
15
55
  #
16
56
  # @api private
17
- def self.underscore(word)
18
- word
19
- .split('::')
20
- .last
21
- .gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
22
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
23
- .downcase
57
+ def self.underscore(str)
58
+ snake_case(str).split('/').last
24
59
  end
25
60
 
26
61
  # Return value or nil if value is empty
data/lib/shale/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Shale
4
4
  # @api private
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
data/lib/shale.rb CHANGED
@@ -4,7 +4,6 @@ require 'yaml'
4
4
 
5
5
  require_relative 'shale/mapper'
6
6
  require_relative 'shale/adapter/json'
7
- require_relative 'shale/adapter/rexml'
8
7
  require_relative 'shale/type/boolean'
9
8
  require_relative 'shale/type/date'
10
9
  require_relative 'shale/type/float'
@@ -73,15 +72,20 @@ module Shale
73
72
  # @api public
74
73
  attr_writer :yaml_adapter
75
74
 
76
- # Set XML adapter
75
+ # XML adapter accessor. Available adapters are Shale::Adapter::REXML,
76
+ # Shale::Adapter::Nokogiri and Shale::Adapter::Ox
77
77
  #
78
78
  # @param [@see Shale::Adapter::REXML] adapter
79
79
  #
80
- # @example
80
+ # @example setting adapter
81
81
  # Shale.xml_adapter = Shale::Adapter::REXML
82
82
  #
83
+ # @example getting adapter
84
+ # Shale.xml_adapter
85
+ # # => Shale::Adapter::REXML
86
+ #
83
87
  # @api public
84
- attr_writer :xml_adapter
88
+ attr_accessor :xml_adapter
85
89
 
86
90
  # Return JSON adapter. By default Shale::Adapter::JSON is used
87
91
  #
@@ -108,20 +112,5 @@ module Shale
108
112
  def yaml_adapter
109
113
  @yaml_adapter || YAML
110
114
  end
111
-
112
- # Return XML adapter. By default Shale::Adapter::REXML is used.
113
- # Available adapters are Shale::Adapter::REXML,
114
- # Shale::Adapter::Nokogiri and Shale::Adapter::Ox
115
- #
116
- # @return [@see Shale::Adapter::REXML]
117
- #
118
- # @example
119
- # Shale.xml_adapter
120
- # # => Shale::Adapter::REXML
121
- #
122
- # @api public
123
- def xml_adapter
124
- @xml_adapter || Adapter::REXML
125
- end
126
115
  end
127
116
  end
data/shale.gemspec CHANGED
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = 'exe'
27
27
  spec.executables = 'shaleb'
28
28
 
29
- spec.required_ruby_version = '>= 2.6.0'
29
+ spec.required_ruby_version = '>= 2.7.0'
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kamil Giszczak
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-30 00:00:00.000000000 Z
11
+ date: 2022-06-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby object mapper and serializer for XML, JSON and YAML.
14
14
  email:
@@ -25,8 +25,14 @@ files:
25
25
  - lib/shale.rb
26
26
  - lib/shale/adapter/json.rb
27
27
  - lib/shale/adapter/nokogiri.rb
28
+ - lib/shale/adapter/nokogiri/document.rb
29
+ - lib/shale/adapter/nokogiri/node.rb
28
30
  - lib/shale/adapter/ox.rb
31
+ - lib/shale/adapter/ox/document.rb
32
+ - lib/shale/adapter/ox/node.rb
29
33
  - lib/shale/adapter/rexml.rb
34
+ - lib/shale/adapter/rexml/document.rb
35
+ - lib/shale/adapter/rexml/node.rb
30
36
  - lib/shale/attribute.rb
31
37
  - lib/shale/error.rb
32
38
  - lib/shale/mapper.rb
@@ -37,17 +43,18 @@ files:
37
43
  - lib/shale/mapping/validator.rb
38
44
  - lib/shale/mapping/xml.rb
39
45
  - lib/shale/schema.rb
46
+ - lib/shale/schema/compiler/boolean.rb
47
+ - lib/shale/schema/compiler/complex.rb
48
+ - lib/shale/schema/compiler/date.rb
49
+ - lib/shale/schema/compiler/float.rb
50
+ - lib/shale/schema/compiler/integer.rb
51
+ - lib/shale/schema/compiler/property.rb
52
+ - lib/shale/schema/compiler/string.rb
53
+ - lib/shale/schema/compiler/time.rb
54
+ - lib/shale/schema/compiler/value.rb
55
+ - lib/shale/schema/compiler/xml_complex.rb
56
+ - lib/shale/schema/compiler/xml_property.rb
40
57
  - lib/shale/schema/json_compiler.rb
41
- - lib/shale/schema/json_compiler/boolean.rb
42
- - lib/shale/schema/json_compiler/date.rb
43
- - lib/shale/schema/json_compiler/float.rb
44
- - lib/shale/schema/json_compiler/integer.rb
45
- - lib/shale/schema/json_compiler/object.rb
46
- - lib/shale/schema/json_compiler/property.rb
47
- - lib/shale/schema/json_compiler/string.rb
48
- - lib/shale/schema/json_compiler/time.rb
49
- - lib/shale/schema/json_compiler/utils.rb
50
- - lib/shale/schema/json_compiler/value.rb
51
58
  - lib/shale/schema/json_generator.rb
52
59
  - lib/shale/schema/json_generator/base.rb
53
60
  - lib/shale/schema/json_generator/boolean.rb
@@ -61,6 +68,7 @@ files:
61
68
  - lib/shale/schema/json_generator/string.rb
62
69
  - lib/shale/schema/json_generator/time.rb
63
70
  - lib/shale/schema/json_generator/value.rb
71
+ - lib/shale/schema/xml_compiler.rb
64
72
  - lib/shale/schema/xml_generator.rb
65
73
  - lib/shale/schema/xml_generator/attribute.rb
66
74
  - lib/shale/schema/xml_generator/complex_type.rb
@@ -72,7 +80,7 @@ files:
72
80
  - lib/shale/schema/xml_generator/typed_attribute.rb
73
81
  - lib/shale/schema/xml_generator/typed_element.rb
74
82
  - lib/shale/type/boolean.rb
75
- - lib/shale/type/composite.rb
83
+ - lib/shale/type/complex.rb
76
84
  - lib/shale/type/date.rb
77
85
  - lib/shale/type/float.rb
78
86
  - lib/shale/type/integer.rb
@@ -99,14 +107,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
107
  requirements:
100
108
  - - ">="
101
109
  - !ruby/object:Gem::Version
102
- version: 2.6.0
110
+ version: 2.7.0
103
111
  required_rubygems_version: !ruby/object:Gem::Requirement
104
112
  requirements:
105
113
  - - ">="
106
114
  - !ruby/object:Gem::Version
107
115
  version: '0'
108
116
  requirements: []
109
- rubygems_version: 3.1.6
117
+ rubygems_version: 3.3.7
110
118
  signing_key:
111
119
  specification_version: 4
112
120
  summary: Ruby object mapper and serializer for XML, JSON and YAML.
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Shale
4
- module Schema
5
- class JSONCompiler
6
- # Module with utility functions
7
- #
8
- # @api private
9
- module Utils
10
- # Convert string to Ruby's class naming convention
11
- #
12
- # @param [String] val
13
- #
14
- # @example
15
- # Shale::Schema::JSONCompiler.classify('foobar')
16
- # # => 'Foobar'
17
- #
18
- # @api private
19
- def self.classify(str)
20
- str = str.to_s.sub(/.*\./, '')
21
-
22
- str = str.sub(/^[a-z\d]*/) { |match| match.capitalize || match }
23
-
24
- str.gsub(%r{(?:_|(/))([a-z\d]*)}i) do
25
- word = Regexp.last_match(2)
26
- substituted = word.capitalize || word
27
- Regexp.last_match(1) ? "::#{substituted}" : substituted
28
- end
29
- end
30
-
31
- # Convert string to snake case
32
- #
33
- # @param [String] val
34
- #
35
- # @example
36
- # Shale::Schema::JSONCompiler.snake_case('FooBar')
37
- # # => 'foo_bar'
38
- #
39
- # @api private
40
- def self.snake_case(str)
41
- return str.to_s unless /[A-Z-]|::/.match?(str)
42
- word = str.to_s.gsub('::', '/')
43
- word = word.gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
44
- "#{Regexp.last_match(1) || Regexp.last_match(2)}_"
45
- end
46
- word = word.tr('-', '_')
47
- word.downcase
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Shale
4
- module Schema
5
- class JSONCompiler
6
- class Value
7
- def name
8
- 'Shale::Type::Value'
9
- end
10
- end
11
- end
12
- end
13
- end