avromatic 1.0.0 → 2.0.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/.rubocop.yml +4 -1
- data/Appraisals +2 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -0
- data/README.md +57 -25
- data/Rakefile +2 -0
- data/avromatic.gemspec +7 -3
- data/lib/avromatic/io/datum_reader.rb +2 -0
- data/lib/avromatic/io/datum_writer.rb +7 -1
- data/lib/avromatic/io.rb +4 -2
- data/lib/avromatic/messaging.rb +2 -0
- data/lib/avromatic/model/attributes.rb +112 -158
- data/lib/avromatic/model/builder.rb +4 -7
- data/lib/avromatic/model/coercion_error.rb +8 -0
- data/lib/avromatic/model/configurable.rb +2 -0
- data/lib/avromatic/model/configuration.rb +2 -0
- data/lib/avromatic/model/{custom_type.rb → custom_type_configuration.rb} +2 -2
- data/lib/avromatic/model/{type_registry.rb → custom_type_registry.rb} +15 -18
- data/lib/avromatic/model/field_helper.rb +20 -0
- data/lib/avromatic/model/message_decoder.rb +2 -0
- data/lib/avromatic/model/messaging_serialization.rb +2 -0
- data/lib/avromatic/model/nested_models.rb +2 -17
- data/lib/avromatic/model/raw_serialization.rb +21 -84
- data/lib/avromatic/model/types/abstract_timestamp_type.rb +57 -0
- data/lib/avromatic/model/types/abstract_type.rb +37 -0
- data/lib/avromatic/model/types/array_type.rb +53 -0
- data/lib/avromatic/model/types/boolean_type.rb +39 -0
- data/lib/avromatic/model/types/custom_type.rb +64 -0
- data/lib/avromatic/model/types/date_type.rb +41 -0
- data/lib/avromatic/model/types/enum_type.rb +56 -0
- data/lib/avromatic/model/types/fixed_type.rb +45 -0
- data/lib/avromatic/model/types/float_type.rb +48 -0
- data/lib/avromatic/model/types/integer_type.rb +39 -0
- data/lib/avromatic/model/types/map_type.rb +74 -0
- data/lib/avromatic/model/types/null_type.rb +39 -0
- data/lib/avromatic/model/types/record_type.rb +57 -0
- data/lib/avromatic/model/types/string_type.rb +48 -0
- data/lib/avromatic/model/types/timestamp_micros_type.rb +32 -0
- data/lib/avromatic/model/types/timestamp_millis_type.rb +32 -0
- data/lib/avromatic/model/types/type_factory.rb +118 -0
- data/lib/avromatic/model/types/union_type.rb +87 -0
- data/lib/avromatic/model/unknown_attribute_error.rb +15 -0
- data/lib/avromatic/model/validation.rb +57 -36
- data/lib/avromatic/model/validation_error.rb +8 -0
- data/lib/avromatic/model/value_object.rb +2 -0
- data/lib/avromatic/model.rb +6 -2
- data/lib/avromatic/model_registry.rb +2 -0
- data/lib/avromatic/patches/schema_validator_patch.rb +2 -0
- data/lib/avromatic/patches.rb +2 -0
- data/lib/avromatic/railtie.rb +2 -0
- data/lib/avromatic/rspec.rb +2 -0
- data/lib/avromatic/version.rb +3 -1
- data/lib/avromatic.rb +9 -4
- metadata +32 -21
- data/lib/avromatic/model/allowed_type_validator.rb +0 -7
- data/lib/avromatic/model/allowed_writer_methods_memoization.rb +0 -16
- data/lib/avromatic/model/attribute/abstract_timestamp.rb +0 -26
- data/lib/avromatic/model/attribute/record.rb +0 -26
- data/lib/avromatic/model/attribute/timestamp_micros.rb +0 -26
- data/lib/avromatic/model/attribute/timestamp_millis.rb +0 -26
- data/lib/avromatic/model/attribute/union.rb +0 -66
- data/lib/avromatic/model/attribute_type/union.rb +0 -29
- data/lib/avromatic/model/logical_types.rb +0 -19
- data/lib/avromatic/model/null_custom_type.rb +0 -21
- data/lib/avromatic/model/passthrough_serializer.rb +0 -10
@@ -1,53 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Avromatic
|
2
4
|
module Model
|
3
5
|
module Validation
|
4
6
|
extend ActiveSupport::Concern
|
7
|
+
include ActiveModel::Validations
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# keys for the Avro map type are always strings and do not require
|
22
|
-
# validation
|
23
|
-
validate_nested_value(map_value).map do |message|
|
24
|
-
"['#{key}']#{message}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
else
|
28
|
-
[]
|
9
|
+
EMPTY_ARRAY = [].freeze
|
10
|
+
|
11
|
+
def self.missing_nested_attributes(attribute, value)
|
12
|
+
if value.is_a?(Array)
|
13
|
+
results = []
|
14
|
+
value.each_with_index do |element, index|
|
15
|
+
nested_results = missing_nested_attributes("#{attribute}[#{index}]", element)
|
16
|
+
results.concat(nested_results)
|
17
|
+
end
|
18
|
+
results
|
19
|
+
elsif value.is_a?(Hash)
|
20
|
+
results = []
|
21
|
+
value.each do |key, element|
|
22
|
+
nested_results = missing_nested_attributes("#{attribute}['#{key}']", element)
|
23
|
+
results.concat(nested_results)
|
29
24
|
end
|
25
|
+
results
|
26
|
+
elsif value.respond_to?(:missing_avro_attributes)
|
27
|
+
value.missing_avro_attributes.map do |missing_child_attribute|
|
28
|
+
"#{attribute}.#{missing_child_attribute}"
|
29
|
+
end
|
30
|
+
else
|
31
|
+
EMPTY_ARRAY
|
30
32
|
end
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
messages = self.class.validate_nested_value(value)
|
38
|
-
messages.each { |message| instance.errors.add(field_name.to_sym, message) }
|
35
|
+
included do
|
36
|
+
# Support the ActiveModel::Validations interface for backwards compatibility
|
37
|
+
validate do |model|
|
38
|
+
model.missing_avro_attributes.each do |missing_attribute|
|
39
|
+
errors.add(:base, "#{missing_attribute} can't be nil")
|
39
40
|
end
|
40
41
|
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def avro_validate!
|
45
|
+
results = missing_avro_attributes
|
46
|
+
if results.present?
|
47
|
+
raise Avromatic::Model::ValidationError.new("#{self.class.name}(#{attributes.inspect}) cannot be " \
|
48
|
+
"serialized because the following attributes are nil: #{results.join(', ')}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def missing_avro_attributes
|
53
|
+
return @missing_attributes if instance_variable_defined?(:@missing_attributes)
|
41
54
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
55
|
+
missing_attributes = []
|
56
|
+
|
57
|
+
self.class.attribute_definitions.each_value do |attribute_definition|
|
58
|
+
value = send(attribute_definition.name)
|
59
|
+
field = attribute_definition.field
|
60
|
+
if value.nil? && field.type.type_sym != :null && attribute_definition.required?
|
61
|
+
missing_attributes << field.name
|
47
62
|
else
|
48
|
-
|
63
|
+
missing_attributes.concat(Avromatic::Model::Validation.missing_nested_attributes(field.name, value))
|
49
64
|
end
|
50
65
|
end
|
66
|
+
|
67
|
+
unless self.class.config.mutable
|
68
|
+
@missing_attributes = missing_attributes.deep_freeze
|
69
|
+
end
|
70
|
+
|
71
|
+
missing_attributes
|
51
72
|
end
|
52
73
|
end
|
53
74
|
end
|
data/lib/avromatic/model.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'avromatic/model/builder'
|
4
|
+
require 'avromatic/model/coercion_error'
|
2
5
|
require 'avromatic/model/message_decoder'
|
3
|
-
require 'avromatic/model/
|
4
|
-
require 'avromatic/model/
|
6
|
+
require 'avromatic/model/custom_type_registry'
|
7
|
+
require 'avromatic/model/validation_error'
|
8
|
+
require 'avromatic/model/unknown_attribute_error'
|
5
9
|
|
6
10
|
module Avromatic
|
7
11
|
module Model
|
data/lib/avromatic/patches.rb
CHANGED
data/lib/avromatic/railtie.rb
CHANGED
data/lib/avromatic/rspec.rb
CHANGED
data/lib/avromatic/version.rb
CHANGED
data/lib/avromatic.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'avromatic/version'
|
2
4
|
require 'avro_schema_registry-client'
|
5
|
+
require 'ice_nine'
|
6
|
+
require 'ice_nine/core_ext/object'
|
3
7
|
require 'avromatic/model'
|
4
8
|
require 'avromatic/model_registry'
|
5
9
|
require 'avromatic/messaging'
|
@@ -9,19 +13,20 @@ require 'avromatic/patches'
|
|
9
13
|
module Avromatic
|
10
14
|
class << self
|
11
15
|
attr_accessor :schema_registry, :registry_url, :schema_store, :logger,
|
12
|
-
:messaging, :
|
16
|
+
:messaging, :custom_type_registry, :nested_models,
|
13
17
|
:use_custom_datum_reader, :use_custom_datum_writer,
|
14
|
-
:use_schema_fingerprint_lookup
|
18
|
+
:use_schema_fingerprint_lookup, :allow_unknown_attributes
|
15
19
|
|
16
|
-
delegate :register_type, to: :
|
20
|
+
delegate :register_type, to: :custom_type_registry
|
17
21
|
end
|
18
22
|
|
19
23
|
self.nested_models = ModelRegistry.new
|
20
24
|
self.logger = Logger.new($stdout)
|
21
|
-
self.
|
25
|
+
self.custom_type_registry = Avromatic::Model::CustomTypeRegistry.new
|
22
26
|
self.use_custom_datum_reader = true
|
23
27
|
self.use_custom_datum_writer = true
|
24
28
|
self.use_schema_fingerprint_lookup = true
|
29
|
+
self.allow_unknown_attributes = false
|
25
30
|
|
26
31
|
def self.configure
|
27
32
|
yield self
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: avromatic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Salsify Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '5.3'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '5.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '5.3'
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '5.0'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '5.3'
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '5.0'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '5.3'
|
@@ -93,7 +93,7 @@ dependencies:
|
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
96
|
+
name: ice_nine
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
99
|
- - ">="
|
@@ -284,28 +284,39 @@ files:
|
|
284
284
|
- lib/avromatic/io/datum_writer.rb
|
285
285
|
- lib/avromatic/messaging.rb
|
286
286
|
- lib/avromatic/model.rb
|
287
|
-
- lib/avromatic/model/allowed_type_validator.rb
|
288
|
-
- lib/avromatic/model/allowed_writer_methods_memoization.rb
|
289
|
-
- lib/avromatic/model/attribute/abstract_timestamp.rb
|
290
|
-
- lib/avromatic/model/attribute/record.rb
|
291
|
-
- lib/avromatic/model/attribute/timestamp_micros.rb
|
292
|
-
- lib/avromatic/model/attribute/timestamp_millis.rb
|
293
|
-
- lib/avromatic/model/attribute/union.rb
|
294
|
-
- lib/avromatic/model/attribute_type/union.rb
|
295
287
|
- lib/avromatic/model/attributes.rb
|
296
288
|
- lib/avromatic/model/builder.rb
|
289
|
+
- lib/avromatic/model/coercion_error.rb
|
297
290
|
- lib/avromatic/model/configurable.rb
|
298
291
|
- lib/avromatic/model/configuration.rb
|
299
|
-
- lib/avromatic/model/
|
300
|
-
- lib/avromatic/model/
|
292
|
+
- lib/avromatic/model/custom_type_configuration.rb
|
293
|
+
- lib/avromatic/model/custom_type_registry.rb
|
294
|
+
- lib/avromatic/model/field_helper.rb
|
301
295
|
- lib/avromatic/model/message_decoder.rb
|
302
296
|
- lib/avromatic/model/messaging_serialization.rb
|
303
297
|
- lib/avromatic/model/nested_models.rb
|
304
|
-
- lib/avromatic/model/null_custom_type.rb
|
305
|
-
- lib/avromatic/model/passthrough_serializer.rb
|
306
298
|
- lib/avromatic/model/raw_serialization.rb
|
307
|
-
- lib/avromatic/model/
|
299
|
+
- lib/avromatic/model/types/abstract_timestamp_type.rb
|
300
|
+
- lib/avromatic/model/types/abstract_type.rb
|
301
|
+
- lib/avromatic/model/types/array_type.rb
|
302
|
+
- lib/avromatic/model/types/boolean_type.rb
|
303
|
+
- lib/avromatic/model/types/custom_type.rb
|
304
|
+
- lib/avromatic/model/types/date_type.rb
|
305
|
+
- lib/avromatic/model/types/enum_type.rb
|
306
|
+
- lib/avromatic/model/types/fixed_type.rb
|
307
|
+
- lib/avromatic/model/types/float_type.rb
|
308
|
+
- lib/avromatic/model/types/integer_type.rb
|
309
|
+
- lib/avromatic/model/types/map_type.rb
|
310
|
+
- lib/avromatic/model/types/null_type.rb
|
311
|
+
- lib/avromatic/model/types/record_type.rb
|
312
|
+
- lib/avromatic/model/types/string_type.rb
|
313
|
+
- lib/avromatic/model/types/timestamp_micros_type.rb
|
314
|
+
- lib/avromatic/model/types/timestamp_millis_type.rb
|
315
|
+
- lib/avromatic/model/types/type_factory.rb
|
316
|
+
- lib/avromatic/model/types/union_type.rb
|
317
|
+
- lib/avromatic/model/unknown_attribute_error.rb
|
308
318
|
- lib/avromatic/model/validation.rb
|
319
|
+
- lib/avromatic/model/validation_error.rb
|
309
320
|
- lib/avromatic/model/value_object.rb
|
310
321
|
- lib/avromatic/model_registry.rb
|
311
322
|
- lib/avromatic/patches.rb
|
@@ -326,7 +337,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
326
337
|
requirements:
|
327
338
|
- - ">="
|
328
339
|
- !ruby/object:Gem::Version
|
329
|
-
version: '
|
340
|
+
version: '2.3'
|
330
341
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
331
342
|
requirements:
|
332
343
|
- - ">="
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Avromatic
|
2
|
-
module Model
|
3
|
-
module AllowedWriterMethodsMemoization
|
4
|
-
def self.included(base)
|
5
|
-
base.class_attribute :virtus_object_allowed_writer_methods
|
6
|
-
base.prepend(InstanceMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
module InstanceMethods
|
10
|
-
def allowed_writer_methods
|
11
|
-
self.class.virtus_object_allowed_writer_methods ||= super
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Avromatic
|
2
|
-
module Model
|
3
|
-
module Attribute
|
4
|
-
|
5
|
-
# This subclass of Virtus::Attribute is used to truncate timestamp values
|
6
|
-
# to the supported precision.
|
7
|
-
class AbstractTimestamp < Virtus::Attribute
|
8
|
-
def coerce(value)
|
9
|
-
return value if value.nil? || value_coerced?(value)
|
10
|
-
|
11
|
-
value.is_a?(Time) ? coerce_time(value) : value
|
12
|
-
end
|
13
|
-
|
14
|
-
def value_coerced?(_value)
|
15
|
-
raise "#{__method__} must be overridden by #{self.class.name}"
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def coerce_time(_value)
|
21
|
-
raise "#{__method__} must be overridden by #{self.class.name}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Avromatic
|
2
|
-
module Model
|
3
|
-
module Attribute
|
4
|
-
|
5
|
-
# This subclass of Virtus::Attribute is defined to ensure that Avromatic
|
6
|
-
# generated models (identified by their inclusion of
|
7
|
-
# Avromatic::Model::Attributes) are always coerced by identifying an
|
8
|
-
# instance of the model or creating a new one.
|
9
|
-
# This is required to coerce models correctly with nested complex types
|
10
|
-
# with Virtus.
|
11
|
-
class Record < Virtus::Attribute
|
12
|
-
primitive Avromatic::Model::Attributes
|
13
|
-
|
14
|
-
def coerce(value)
|
15
|
-
return value if value.nil? || value.is_a?(primitive)
|
16
|
-
|
17
|
-
primitive.new(value)
|
18
|
-
end
|
19
|
-
|
20
|
-
def value_coerced?(value)
|
21
|
-
value.is_a?(primitive)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'avromatic/model/attribute/abstract_timestamp'
|
2
|
-
|
3
|
-
module Avromatic
|
4
|
-
module Model
|
5
|
-
module Attribute
|
6
|
-
|
7
|
-
# This subclass is used to truncate timestamp values to microseconds.
|
8
|
-
class TimestampMicros < AbstractTimestamp
|
9
|
-
|
10
|
-
def value_coerced?(value)
|
11
|
-
value.is_a?(Time) && value.nsec % 1000 == 0
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def coerce_time(value)
|
17
|
-
# value is coerced to a local Time
|
18
|
-
# The Avro representation of a timestamp is Epoch seconds, independent
|
19
|
-
# of time zone.
|
20
|
-
Time.at(value.to_i, value.usec)
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'avromatic/model/attribute/abstract_timestamp'
|
2
|
-
|
3
|
-
module Avromatic
|
4
|
-
module Model
|
5
|
-
module Attribute
|
6
|
-
|
7
|
-
# This subclass is used to truncate timestamp values to milliseconds.
|
8
|
-
class TimestampMillis < AbstractTimestamp
|
9
|
-
|
10
|
-
def value_coerced?(value)
|
11
|
-
value.is_a?(Time) && value.usec % 1000 == 0
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def coerce_time(value)
|
17
|
-
# value is coerced to a local Time
|
18
|
-
# The Avro representation of a timestamp is Epoch seconds, independent
|
19
|
-
# of time zone.
|
20
|
-
Time.at(value.to_i, value.usec / 1000 * 1000)
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'avromatic/model/attribute_type/union'
|
2
|
-
require 'avromatic/io'
|
3
|
-
|
4
|
-
module Avromatic
|
5
|
-
module Model
|
6
|
-
module Attribute
|
7
|
-
|
8
|
-
# This subclass of Virtus::Attribute is used for any unions that are
|
9
|
-
# defined as subclasses of the primitive Avromatic::Model::AttributeType::Union.
|
10
|
-
# Values are coerced by first checking if they already match one of the
|
11
|
-
# member types, and then by attempting to coerce to each member type in
|
12
|
-
# order.
|
13
|
-
class Union < Virtus::Attribute
|
14
|
-
primitive Avromatic::Model::AttributeType::Union
|
15
|
-
|
16
|
-
MEMBER_INDEX = ::Avromatic::IO::DatumReader::UNION_MEMBER_INDEX
|
17
|
-
|
18
|
-
def initialize(*)
|
19
|
-
super
|
20
|
-
|
21
|
-
primitive.types.each do |type|
|
22
|
-
member_attributes << Virtus::Attribute.build(type)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def coerce(input)
|
27
|
-
return input if value_coerced?(input)
|
28
|
-
|
29
|
-
result = nil
|
30
|
-
if input && input.key?(MEMBER_INDEX)
|
31
|
-
result = safe_coerce(member_attributes[input.delete(MEMBER_INDEX)], input)
|
32
|
-
else
|
33
|
-
member_attributes.find do |union_attribute|
|
34
|
-
result = safe_coerce(union_attribute, input)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
result
|
38
|
-
end
|
39
|
-
|
40
|
-
def value_coerced?(value)
|
41
|
-
member_attributes.any? do |union_attribute|
|
42
|
-
union_attribute.value_coerced?(value)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def safe_coerce(member_attribute, input)
|
49
|
-
coerced = member_attribute.coerce(input)
|
50
|
-
|
51
|
-
if coerced.is_a?(Avromatic::Model::Attributes)
|
52
|
-
coerced if coerced.valid?
|
53
|
-
elsif member_attribute.coerced?(coerced)
|
54
|
-
coerced
|
55
|
-
end
|
56
|
-
rescue StandardError
|
57
|
-
nil
|
58
|
-
end
|
59
|
-
|
60
|
-
def member_attributes
|
61
|
-
@member_attributes ||= Array.new
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Avromatic
|
2
|
-
module Model
|
3
|
-
module AttributeType
|
4
|
-
|
5
|
-
# This class is used as the base class for Virtus attributes that
|
6
|
-
# represent unions. A subclass is generated using Union[*types]. This
|
7
|
-
# subclass is specified when defining a Virtus attribute.
|
8
|
-
class Union
|
9
|
-
class << self
|
10
|
-
attr_reader :types
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
attr_writer :types
|
15
|
-
end
|
16
|
-
|
17
|
-
# Factory method to define Union types with the specified list of
|
18
|
-
# types (classes).
|
19
|
-
def self.[](*types)
|
20
|
-
Class.new(self).tap do |klass|
|
21
|
-
klass.types = types
|
22
|
-
# See https://github.com/solnic/virtus/issues/284#issuecomment-56405137
|
23
|
-
Axiom::Types::Object.new { primitive(klass) }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'avromatic/model/attribute/timestamp_micros'
|
2
|
-
require 'avromatic/model/attribute/timestamp_millis'
|
3
|
-
|
4
|
-
module Avromatic
|
5
|
-
module Model
|
6
|
-
module LogicalTypes
|
7
|
-
|
8
|
-
LOGICAL_TYPE_MAP = {
|
9
|
-
'date' => Date,
|
10
|
-
'timestamp-micros' => Avromatic::Model::Attribute::TimestampMicros,
|
11
|
-
'timestamp-millis' => Avromatic::Model::Attribute::TimestampMillis
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
def self.value_class(logical_type)
|
15
|
-
LOGICAL_TYPE_MAP[logical_type]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Avromatic
|
2
|
-
module Model
|
3
|
-
|
4
|
-
# This module is used to implement the null object pattern for a CustomType.
|
5
|
-
module NullCustomType
|
6
|
-
class << self
|
7
|
-
def value_class
|
8
|
-
nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def deserializer
|
12
|
-
nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def serializer
|
16
|
-
nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|