shale 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +263 -69
  4. data/lib/shale/adapter/json.rb +10 -7
  5. data/lib/shale/adapter/nokogiri.rb +1 -1
  6. data/lib/shale/adapter/ox.rb +2 -1
  7. data/lib/shale/adapter/toml_rb.rb +5 -3
  8. data/lib/shale/adapter/tomlib.rb +36 -0
  9. data/lib/shale/error.rb +26 -1
  10. data/lib/shale/mapper.rb +36 -30
  11. data/lib/shale/mapping/descriptor/dict.rb +10 -1
  12. data/lib/shale/mapping/dict.rb +4 -3
  13. data/lib/shale/mapping/dict_base.rb +29 -2
  14. data/lib/shale/schema/json_generator/base.rb +9 -3
  15. data/lib/shale/schema/json_generator/boolean.rb +2 -1
  16. data/lib/shale/schema/json_generator/collection.rb +18 -2
  17. data/lib/shale/schema/json_generator/date.rb +3 -1
  18. data/lib/shale/schema/json_generator/float.rb +7 -1
  19. data/lib/shale/schema/json_generator/integer.rb +7 -1
  20. data/lib/shale/schema/json_generator/object.rb +12 -2
  21. data/lib/shale/schema/json_generator/string.rb +6 -1
  22. data/lib/shale/schema/json_generator/time.rb +3 -1
  23. data/lib/shale/schema/json_generator/value.rb +2 -1
  24. data/lib/shale/schema/json_generator.rb +7 -3
  25. data/lib/shale/schema/xml_compiler.rb +12 -12
  26. data/lib/shale/type/boolean.rb +2 -0
  27. data/lib/shale/type/complex.rb +43 -18
  28. data/lib/shale/type/date.rb +2 -0
  29. data/lib/shale/type/float.rb +2 -0
  30. data/lib/shale/type/integer.rb +2 -0
  31. data/lib/shale/type/string.rb +2 -0
  32. data/lib/shale/type/time.rb +2 -0
  33. data/lib/shale/type.rb +56 -0
  34. data/lib/shale/utils.rb +1 -1
  35. data/lib/shale/version.rb +1 -1
  36. data/lib/shale.rb +18 -20
  37. data/shale.gemspec +3 -1
  38. metadata +21 -5
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tomlib'
4
+
5
+ module Shale
6
+ module Adapter
7
+ # Tomlib adapter
8
+ #
9
+ # @api public
10
+ class Tomlib
11
+ # Parse TOML into Hash
12
+ #
13
+ # @param [String] toml TOML document
14
+ # @param [Hash] options
15
+ #
16
+ # @return [Hash]
17
+ #
18
+ # @api private
19
+ def self.load(toml, **_options)
20
+ ::Tomlib.load(toml)
21
+ end
22
+
23
+ # Serialize Hash into TOML
24
+ #
25
+ # @param [Hash] obj Hash object
26
+ # @param [Hash] options
27
+ #
28
+ # @return [String]
29
+ #
30
+ # @api private
31
+ def self.dump(obj, **options)
32
+ ::Tomlib.dump(obj, **options)
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/shale/error.rb CHANGED
@@ -9,7 +9,8 @@ module Shale
9
9
 
10
10
  # To use Tomlib:
11
11
  # Make sure tomlib is installed eg. execute: gem install tomlib
12
- Shale.toml_adapter = Tomlib
12
+ require 'shale/adapter/tomlib'
13
+ Shale.toml_adapter = Shale::Adapter::Tomlib
13
14
 
14
15
  # To use toml-rb:
15
16
  # Make sure toml-rb is installed eg. execute: gem install toml-rb
@@ -38,6 +39,18 @@ module Shale
38
39
  Shale.xml_adapter = Shale::Adapter::Ox
39
40
  MSG
40
41
 
42
+ # Error message displayed when CSV adapter is not set
43
+ # @api private
44
+ CSV_ADAPTER_NOT_SET_MESSAGE = <<~MSG
45
+ CSV Adapter is not set.
46
+ To use Shale with CSV documents you have to install parser and set adapter.
47
+
48
+ # To use csv gem:
49
+ # Make sure csv is installed eg. execute: gem install csv
50
+ require 'shale/adapter/csv'
51
+ Shale.csv_adapter = Shale::Adapter::CSV
52
+ MSG
53
+
41
54
  # Error for assigning value to not existing attribute
42
55
  #
43
56
  # @api private
@@ -92,6 +105,18 @@ module Shale
92
105
  class NotAShaleMapperError < ShaleError
93
106
  end
94
107
 
108
+ # Error for registering class that is not a valid Type::Value
109
+ #
110
+ # @api private
111
+ class NotATypeValueError < ShaleError
112
+ end
113
+
114
+ # Error for using unknown symbol type
115
+ #
116
+ # @api private
117
+ class UnknownTypeError < ShaleError
118
+ end
119
+
95
120
  # Raised when receiver attribute is not defined
96
121
  #
97
122
  # @api private
data/lib/shale/mapper.rb CHANGED
@@ -5,6 +5,7 @@ require_relative 'error'
5
5
  require_relative 'utils'
6
6
  require_relative 'mapping/dict'
7
7
  require_relative 'mapping/xml'
8
+ require_relative 'type'
8
9
  require_relative 'type/complex'
9
10
 
10
11
  module Shale
@@ -12,16 +13,16 @@ module Shale
12
13
  #
13
14
  # @example
14
15
  # class Address < Shale::Mapper
15
- # attribute :city, Shale::Type::String
16
- # attribute :street, Shale::Type::String
17
- # attribute :state, Shale::Type::Integer
18
- # attribute :zip, Shale::Type::String
16
+ # attribute :city, :string
17
+ # attribute :street, :string
18
+ # attribute :state, :string
19
+ # attribute :zip, :string
19
20
  # end
20
21
  #
21
22
  # class Person < Shale::Mapper
22
- # attribute :first_name, Shale::Type::String
23
- # attribute :last_name, Shale::Type::String
24
- # attribute :age, Shale::Type::Integer
23
+ # attribute :first_name, :string
24
+ # attribute :last_name, :string
25
+ # attribute :age, :integer
25
26
  # attribute :address, Address
26
27
  # end
27
28
  #
@@ -144,18 +145,19 @@ module Shale
144
145
  # Define attribute on class
145
146
  #
146
147
  # @param [Symbol] name Name of the attribute
147
- # @param [Shale::Type::Value] type Type of the attribute
148
+ # @param [Symbol, Class<Shale::Type::Value>] type Type of the attribute
148
149
  # @param [Boolean] collection Is the attribute a collection
149
150
  # @param [Proc] default Default value for the attribute
150
151
  #
151
152
  # @raise [DefaultNotCallableError] when attribute's default is not callable
153
+ # @raise [UnknownTypeError] when type is a symbol and not found in the registry
152
154
  #
153
155
  # @example
154
156
  # class Person < Shale::Mapper
155
- # attribute :first_name, Shale::Type::String
156
- # attribute :last_name, Shale::Type::String
157
- # attribute :age, Shale::Type::Integer, default: -> { 1 }
158
- # attribute :hobbies, Shale::Type::String, collection: true
157
+ # attribute :first_name, :string
158
+ # attribute :last_name, :string
159
+ # attribute :age, :integer, default: -> { 1 }
160
+ # attribute :hobbies, :string, collection: true
159
161
  # end
160
162
  #
161
163
  # person = Person.new
@@ -177,6 +179,10 @@ module Shale
177
179
  raise DefaultNotCallableError.new(to_s, name)
178
180
  end
179
181
 
182
+ if type.is_a?(Symbol)
183
+ type = Type.lookup(type)
184
+ end
185
+
180
186
  @attributes[name] = Attribute.new(name, type, collection, default)
181
187
 
182
188
  @hash_mapping.map(name.to_s, to: name) unless @hash_mapping.finalized?
@@ -201,9 +207,9 @@ module Shale
201
207
  #
202
208
  # @example
203
209
  # class Person < Shale::Mapper
204
- # attribute :first_name, Shale::Type::String
205
- # attribute :last_name, Shale::Type::String
206
- # attribute :age, Shale::Type::Integer
210
+ # attribute :first_name, :string
211
+ # attribute :last_name, :string
212
+ # attribute :age, :integer
207
213
  #
208
214
  # hsh do
209
215
  # map 'firstName', to: :first_name
@@ -225,9 +231,9 @@ module Shale
225
231
  #
226
232
  # @example
227
233
  # class Person < Shale::Mapper
228
- # attribute :first_name, Shale::Type::String
229
- # attribute :last_name, Shale::Type::String
230
- # attribute :age, Shale::Type::Integer
234
+ # attribute :first_name, :string
235
+ # attribute :last_name, :string
236
+ # attribute :age, :integer
231
237
  #
232
238
  # json do
233
239
  # map 'firstName', to: :first_name
@@ -249,9 +255,9 @@ module Shale
249
255
  #
250
256
  # @example
251
257
  # class Person < Shale::Mapper
252
- # attribute :first_name, Shale::Type::String
253
- # attribute :last_name, Shale::Type::String
254
- # attribute :age, Shale::Type::Integer
258
+ # attribute :first_name, :string
259
+ # attribute :last_name, :string
260
+ # attribute :age, :integer
255
261
  #
256
262
  # yaml do
257
263
  # map 'first_name', to: :first_name
@@ -273,9 +279,9 @@ module Shale
273
279
  #
274
280
  # @example
275
281
  # class Person < Shale::Mapper
276
- # attribute :first_name, Shale::Type::String
277
- # attribute :last_name, Shale::Type::String
278
- # attribute :age, Shale::Type::Integer
282
+ # attribute :first_name, :string
283
+ # attribute :last_name, :string
284
+ # attribute :age, :integer
279
285
  #
280
286
  # toml do
281
287
  # map 'first_name', to: :first_name
@@ -297,9 +303,9 @@ module Shale
297
303
  #
298
304
  # @example
299
305
  # class Person < Shale::Mapper
300
- # attribute :first_name, Shale::Type::String
301
- # attribute :last_name, Shale::Type::String
302
- # attribute :age, Shale::Type::Integer
306
+ # attribute :first_name, :string
307
+ # attribute :last_name, :string
308
+ # attribute :age, :integer
303
309
  #
304
310
  # csv do
305
311
  # map 'first_name', to: :first_name
@@ -321,9 +327,9 @@ module Shale
321
327
  #
322
328
  # @example
323
329
  # class Person < Shale::Mapper
324
- # attribute :first_name, Shale::Type::String
325
- # attribute :last_name, Shale::Type::String
326
- # attribute :age, Shale::Type::Integer
330
+ # attribute :first_name, :string
331
+ # attribute :last_name, :string
332
+ # attribute :age, :integer
327
333
  #
328
334
  # xml do
329
335
  # root 'Person'
@@ -49,6 +49,13 @@ module Shale
49
49
  # @api private
50
50
  attr_reader :group
51
51
 
52
+ # Return schema hash
53
+ #
54
+ # @return [Hash]
55
+ #
56
+ # @api private
57
+ attr_reader :schema
58
+
52
59
  # Initialize instance
53
60
  #
54
61
  # @param [String] name
@@ -57,14 +64,16 @@ module Shale
57
64
  # @param [Hash, nil] methods
58
65
  # @param [String, nil] group
59
66
  # @param [true, false] render_nil
67
+ # @param [Hash, nil] schema
60
68
  #
61
69
  # @api private
62
- def initialize(name:, attribute:, receiver:, methods:, group:, render_nil:)
70
+ def initialize(name:, attribute:, receiver:, methods:, group:, render_nil:, schema: nil)
63
71
  @name = name
64
72
  @attribute = attribute
65
73
  @receiver = receiver
66
74
  @group = group
67
75
  @render_nil = render_nil
76
+ @schema = schema
68
77
 
69
78
  if methods
70
79
  @method_from = methods[:from]
@@ -16,12 +16,13 @@ module Shale
16
16
  # @param [Symbol, nil] receiver
17
17
  # @param [Hash, nil] using
18
18
  # @param [true, false, nil] render_nil
19
+ # @param [Hash, nil] schema
19
20
  #
20
21
  # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
21
22
  #
22
- # @api private
23
- def map(key, to: nil, receiver: nil, using: nil, render_nil: nil)
24
- super(key, to: to, receiver: receiver, using: using, render_nil: render_nil)
23
+ # @api public
24
+ def map(key, to: nil, receiver: nil, using: nil, render_nil: nil, schema: nil)
25
+ super(key, to: to, receiver: receiver, using: using, render_nil: render_nil, schema: schema)
25
26
  end
26
27
 
27
28
  # Set render_nil default
@@ -16,6 +16,13 @@ module Shale
16
16
  # @api private
17
17
  attr_reader :keys
18
18
 
19
+ # Return hash for hash with properties for root Object
20
+ #
21
+ # @return [Hash]
22
+ #
23
+ # @api private
24
+ attr_reader :root
25
+
19
26
  # Initialize instance
20
27
  #
21
28
  # @param [true, false] render_nil_default
@@ -23,6 +30,7 @@ module Shale
23
30
  # @api private
24
31
  def initialize(render_nil_default: false)
25
32
  @keys = {}
33
+ @root = {}
26
34
  @finalized = false
27
35
  @render_nil_default = render_nil_default
28
36
  end
@@ -35,11 +43,12 @@ module Shale
35
43
  # @param [Hash, nil] using
36
44
  # @param [String, nil] group
37
45
  # @param [true, false, nil] render_nil
46
+ # @param [Hash, nil] schema
38
47
  #
39
48
  # @raise [IncorrectMappingArgumentsError] when arguments are incorrect
40
49
  #
41
50
  # @api private
42
- def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil)
51
+ def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil, schema: nil)
43
52
  Validator.validate_arguments(key, to, receiver, using)
44
53
 
45
54
  @keys[key] = Descriptor::Dict.new(
@@ -48,10 +57,28 @@ module Shale
48
57
  receiver: receiver,
49
58
  methods: using,
50
59
  group: group,
51
- render_nil: render_nil.nil? ? @render_nil_default : render_nil
60
+ render_nil: render_nil.nil? ? @render_nil_default : render_nil,
61
+ schema: schema
52
62
  )
53
63
  end
54
64
 
65
+ # Allow schema properties to be set on the object
66
+ #
67
+ # @param [Integer] min_properties
68
+ # @param [Integer] max_properties
69
+ # @param [Hash] dependent_required
70
+ # @param [Boolean] additional_properties
71
+ #
72
+ # @api public
73
+ def properties(min_properties: nil, max_properties: nil, dependent_required: nil, additional_properties: nil)
74
+ @root = {
75
+ min_properties: min_properties,
76
+ max_properties: max_properties,
77
+ dependent_required: dependent_required,
78
+ additional_properties: additional_properties,
79
+ }
80
+ end
81
+
55
82
  # Set the "finalized" instance variable to true
56
83
  #
57
84
  # @api private
@@ -12,15 +12,21 @@ module Shale
12
12
  # @api private
13
13
  attr_reader :name
14
14
 
15
- # Return nullable
15
+ # Return schema hash
16
+ #
17
+ # @api private
18
+ attr_reader :schema
19
+
20
+ # Set nullable
16
21
  #
17
22
  # @api private
18
23
  attr_writer :nullable
19
24
 
20
- def initialize(name, default: nil)
25
+ def initialize(name, default: nil, schema: nil)
21
26
  @name = name.gsub('::', '_')
22
27
  @default = default
23
- @nullable = true
28
+ @schema = schema || {}
29
+ @nullable = !schema&.[](:required)
24
30
  end
25
31
 
26
32
  # Return JSON Schema fragment as Ruby Hash
@@ -15,7 +15,8 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'boolean' }
18
+ { 'type' => 'boolean',
19
+ 'description' => schema[:description] }.compact
19
20
  end
20
21
  end
21
22
  end
@@ -7,13 +7,20 @@ module Shale
7
7
  #
8
8
  # @api private
9
9
  class Collection
10
+ # Return schema hash
11
+ #
12
+ # @api private
13
+ attr_reader :schema
14
+
10
15
  # Initialize Collection object
11
16
  #
12
17
  # @param [Shale::Schema::JSONGenerator::Base] type
18
+ # @param [Hash] schema
13
19
  #
14
20
  # @api private
15
- def initialize(type)
21
+ def initialize(type, schema: nil)
16
22
  @type = type
23
+ @schema = schema
17
24
  end
18
25
 
19
26
  # Delegate name to wrapped type object
@@ -31,7 +38,16 @@ module Shale
31
38
  #
32
39
  # @api private
33
40
  def as_json
34
- { 'type' => 'array', 'items' => @type.as_type }
41
+ schema = @schema || {}
42
+
43
+ { 'type' => 'array',
44
+ 'items' => @type.as_type,
45
+ 'minItems' => schema[:min_items],
46
+ 'maxItems' => schema[:max_items],
47
+ 'uniqueItems' => schema[:unique],
48
+ 'minContains' => schema[:min_contains],
49
+ 'maxContains' => schema[:max_contains],
50
+ 'description' => schema[:description] }.compact
35
51
  end
36
52
  end
37
53
  end
@@ -15,7 +15,9 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'string', 'format' => 'date' }
18
+ { 'type' => 'string',
19
+ 'format' => 'date',
20
+ 'description' => schema[:description] }.compact
19
21
  end
20
22
  end
21
23
  end
@@ -15,7 +15,13 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'number' }
18
+ { 'type' => 'number',
19
+ 'exclusiveMinimum' => schema[:exclusive_minimum],
20
+ 'exclusiveMaximum' => schema[:exclusive_maximum],
21
+ 'minimum' => schema[:minimum],
22
+ 'maximum' => schema[:maximum],
23
+ 'multipleOf' => schema[:multiple_of],
24
+ 'description' => schema[:description] }.compact
19
25
  end
20
26
  end
21
27
  end
@@ -15,7 +15,13 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'integer' }
18
+ { 'type' => 'integer',
19
+ 'exclusiveMinimum' => schema[:exclusive_minimum],
20
+ 'exclusiveMaximum' => schema[:exclusive_maximum],
21
+ 'minimum' => schema[:minimum],
22
+ 'maximum' => schema[:maximum],
23
+ 'multipleOf' => schema[:multiple_of],
24
+ 'description' => schema[:description] }.compact
19
25
  end
20
26
  end
21
27
  end
@@ -16,10 +16,12 @@ module Shale
16
16
  # Array<Shale::Schema::JSONGenerator::Base,
17
17
  # Shale::Schema::JSONGenerator::Collection>
18
18
  # ] properties
19
+ # @param [Hash] root
19
20
  #
20
21
  # @api private
21
- def initialize(name, properties)
22
+ def initialize(name, properties, root)
22
23
  super(name)
24
+ @root = root
23
25
  @properties = properties
24
26
  end
25
27
 
@@ -29,10 +31,18 @@ module Shale
29
31
  #
30
32
  # @api private
31
33
  def as_type
34
+ required_props = @properties.filter_map { |prop| prop.name if prop&.schema&.[](:required) }
35
+
32
36
  {
33
37
  'type' => 'object',
34
38
  'properties' => @properties.to_h { |el| [el.name, el.as_json] },
35
- }
39
+ 'required' => required_props.empty? ? nil : required_props,
40
+ 'minProperties' => @root[:min_properties],
41
+ 'maxProperties' => @root[:max_properties],
42
+ 'dependentRequired' => @root[:dependent_required],
43
+ 'description' => @root[:description],
44
+ 'additionalProperties' => @root[:additional_properties],
45
+ }.compact
36
46
  end
37
47
  end
38
48
  end
@@ -15,7 +15,12 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'string' }
18
+ { 'type' => 'string',
19
+ 'format' => schema[:format],
20
+ 'minLength' => schema[:min_length],
21
+ 'maxLength' => schema[:max_length],
22
+ 'pattern' => schema[:pattern],
23
+ 'description' => schema[:description] }.compact
19
24
  end
20
25
  end
21
26
  end
@@ -15,7 +15,9 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => 'string', 'format' => 'date-time' }
18
+ { 'type' => 'string',
19
+ 'format' => 'date-time',
20
+ 'description' => schema[:description] }.compact
19
21
  end
20
22
  end
21
23
  end
@@ -15,7 +15,8 @@ module Shale
15
15
  #
16
16
  # @api private
17
17
  def as_type
18
- { 'type' => %w[boolean integer number object string] }
18
+ { 'type' => %w[boolean integer number object string],
19
+ 'description' => schema[:description] }.compact
19
20
  end
20
21
  end
21
22
  end
@@ -96,14 +96,18 @@ module Shale
96
96
  default = attribute.type.as_json(value)
97
97
  end
98
98
 
99
- json_type = json_klass.new(mapping.name, default: default)
99
+ json_type = json_klass.new(
100
+ mapping.name,
101
+ default: default,
102
+ schema: mapping.schema
103
+ )
100
104
  end
101
105
 
102
- json_type = Collection.new(json_type) if attribute.collection?
106
+ json_type = Collection.new(json_type, schema: mapping.schema) if attribute.collection?
103
107
  properties << json_type
104
108
  end
105
109
 
106
- objects << Object.new(type.model.name, properties)
110
+ objects << Object.new(type.model.name, properties, type.json_mapping.root)
107
111
  end
108
112
 
109
113
  Schema.new(objects, id: id, title: title, description: description).as_json
@@ -34,51 +34,51 @@ module Shale
34
34
 
35
35
  # XML Schema "schema" element name
36
36
  # @api private
37
- XS_SCHEMA = "#{XS_NAMESPACE_URI}:schema"
37
+ XS_SCHEMA = "#{XS_NAMESPACE_URI}:schema".freeze
38
38
 
39
39
  # XML Schema "element" element name
40
40
  # @api private
41
- XS_ELEMENT = "#{XS_NAMESPACE_URI}:element"
41
+ XS_ELEMENT = "#{XS_NAMESPACE_URI}:element".freeze
42
42
 
43
43
  # XML Schema "attribute" element name
44
44
  # @api private
45
- XS_ATTRIBUTE = "#{XS_NAMESPACE_URI}:attribute"
45
+ XS_ATTRIBUTE = "#{XS_NAMESPACE_URI}:attribute".freeze
46
46
 
47
47
  # XML Schema "attribute" element name
48
48
  # @api private
49
- XS_SIMPLE_TYPE = "#{XS_NAMESPACE_URI}:simpleType"
49
+ XS_SIMPLE_TYPE = "#{XS_NAMESPACE_URI}:simpleType".freeze
50
50
 
51
51
  # XML Schema "simpleContent" element name
52
52
  # @api private
53
- XS_SIMPLE_CONTENT = "#{XS_NAMESPACE_URI}:simpleContent"
53
+ XS_SIMPLE_CONTENT = "#{XS_NAMESPACE_URI}:simpleContent".freeze
54
54
 
55
55
  # XML Schema "restriction" element name
56
56
  # @api private
57
- XS_RESTRICTION = "#{XS_NAMESPACE_URI}:restriction"
57
+ XS_RESTRICTION = "#{XS_NAMESPACE_URI}:restriction".freeze
58
58
 
59
59
  # XML Schema "group" element name
60
60
  # @api private
61
- XS_GROUP = "#{XS_NAMESPACE_URI}:group"
61
+ XS_GROUP = "#{XS_NAMESPACE_URI}:group".freeze
62
62
 
63
63
  # XML Schema "attributeGroup" element name
64
64
  # @api private
65
- XS_ATTRIBUTE_GROUP = "#{XS_NAMESPACE_URI}:attributeGroup"
65
+ XS_ATTRIBUTE_GROUP = "#{XS_NAMESPACE_URI}:attributeGroup".freeze
66
66
 
67
67
  # XML Schema "complexType" element name
68
68
  # @api private
69
- XS_COMPLEX_TYPE = "#{XS_NAMESPACE_URI}:complexType"
69
+ XS_COMPLEX_TYPE = "#{XS_NAMESPACE_URI}:complexType".freeze
70
70
 
71
71
  # XML Schema "complexContent" element name
72
72
  # @api private
73
- XS_COMPLEX_CONTENT = "#{XS_NAMESPACE_URI}:complexContent"
73
+ XS_COMPLEX_CONTENT = "#{XS_NAMESPACE_URI}:complexContent".freeze
74
74
 
75
75
  # XML Schema "extension" element name
76
76
  # @api private
77
- XS_EXTENSION = "#{XS_NAMESPACE_URI}:extension"
77
+ XS_EXTENSION = "#{XS_NAMESPACE_URI}:extension".freeze
78
78
 
79
79
  # XML Schema "anyType" type
80
80
  # @api private
81
- XS_TYPE_ANY = "#{XS_NAMESPACE_URI}:anyType"
81
+ XS_TYPE_ANY = "#{XS_NAMESPACE_URI}:anyType".freeze
82
82
 
83
83
  # XML Schema "date" types
84
84
  # @api private
@@ -29,5 +29,7 @@ module Shale
29
29
  !FALSE_VALUES.include?(value) unless value.nil?
30
30
  end
31
31
  end
32
+
33
+ register(:boolean, Boolean)
32
34
  end
33
35
  end