shale 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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