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