Class: Skit::Serialization::Processor::Union
- Extended by:
- T::Sig
- Defined in:
- lib/skit/serialization/processor/union.rb
Class Method Summary collapse
- .boolean_union?(type_spec) ⇒ Boolean
- .contains_nil_class?(type_spec) ⇒ Boolean
- .handles?(type_spec) ⇒ Boolean
- .struct_types(type_spec) ⇒ Object
Instance Method Summary collapse
- #deserialize(value, path: Path.new) ⇒ Object
-
#initialize(type_spec, registry:) ⇒ Union
constructor
A new instance of Union.
- #serialize(value, path: Path.new) ⇒ Object
Methods inherited from Base
Constructor Details
#initialize(type_spec, registry:) ⇒ Union
Returns a new instance of Union.
20 21 22 23 24 25 26 |
# File 'lib/skit/serialization/processor/union.rb', line 20 def initialize(type_spec, registry:) super @struct_classes = T.let( self.class.struct_types(type_spec), T::Array[T.class_of(T::Struct)] ) end |
Class Method Details
.boolean_union?(type_spec) ⇒ Boolean
74 75 76 77 78 79 |
# File 'lib/skit/serialization/processor/union.rb', line 74 def boolean_union?(type_spec) raw_types = type_spec.types.filter_map do |t| t.is_a?(T::Types::Simple) ? t.raw_type : nil end raw_types.sort_by { |t| t.name.to_s } == [FalseClass, TrueClass] end |
.contains_nil_class?(type_spec) ⇒ Boolean
67 68 69 70 71 |
# File 'lib/skit/serialization/processor/union.rb', line 67 def contains_nil_class?(type_spec) type_spec.types.any? do |t| t.is_a?(T::Types::Simple) && t.raw_type == NilClass end end |
.handles?(type_spec) ⇒ Boolean
11 12 13 14 15 16 17 |
# File 'lib/skit/serialization/processor/union.rb', line 11 def self.handles?(type_spec) return false unless type_spec.is_a?(T::Types::Union) return false if contains_nil_class?(type_spec) return false if boolean_union?(type_spec) struct_types(type_spec).length == type_spec.types.length end |
.struct_types(type_spec) ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/skit/serialization/processor/union.rb', line 82 def struct_types(type_spec) type_spec.types.filter_map do |t| next unless t.is_a?(T::Types::Simple) klass = t.raw_type klass if klass.is_a?(Class) && klass < T::Struct end end |
Instance Method Details
#deserialize(value, path: Path.new) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/skit/serialization/processor/union.rb', line 44 def deserialize(value, path: Path.new) return value if value_is_union_member?(value) unless value.is_a?(::Hash) raise DeserializeError.new("Expected Hash or union member struct, got #{value.class}", path: path) end @struct_classes.each do |struct_class| result = try_deserialize(value, struct_class, path: path) return result if result end raise DeserializeError.new( "No matching struct found for union: #{@struct_classes.map(&:name).join(", ")}", path: path ) end |
#serialize(value, path: Path.new) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/skit/serialization/processor/union.rb', line 29 def serialize(value, path: Path.new) struct_class = find_struct_class_for_value(value) unless struct_class raise SerializeError.new( "#{value.class} is not a member of this union: #{@struct_classes.map(&:name).join(", ")}", path: path ) end processor = @registry.processor_for(struct_class) processor.serialize(value, path: path) end |