sorbet-schema 0.9.1 → 0.9.3

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.
data/lib/typed/schema.rb CHANGED
@@ -20,12 +20,12 @@ module Typed
20
20
 
21
21
  sig { params(hash: Typed::HashSerializer::InputHash).returns(Typed::Serializer::DeserializeResult) }
22
22
  def from_hash(hash)
23
- Typed::HashSerializer.new(schema: self).deserialize(hash)
23
+ hash_serializer.deserialize(hash)
24
24
  end
25
25
 
26
26
  sig { params(json: String).returns(Typed::Serializer::DeserializeResult) }
27
27
  def from_json(json)
28
- Typed::JSONSerializer.new(schema: self).deserialize(json)
28
+ json_serializer.deserialize(json)
29
29
  end
30
30
 
31
31
  sig { params(field_name: Symbol, serializer: Field::InlineSerializer).returns(Schema) }
@@ -41,5 +41,19 @@ module Typed
41
41
  end
42
42
  )
43
43
  end
44
+
45
+ private
46
+
47
+ sig { returns(Typed::HashSerializer) }
48
+ def hash_serializer
49
+ @hash_serializer = T.let(@hash_serializer, T.nilable(Typed::HashSerializer))
50
+ @hash_serializer ||= Typed::HashSerializer.new(schema: self)
51
+ end
52
+
53
+ sig { returns(Typed::JSONSerializer) }
54
+ def json_serializer
55
+ @json_serializer = T.let(@json_serializer, T.nilable(Typed::JSONSerializer))
56
+ @json_serializer ||= Typed::JSONSerializer.new(schema: self)
57
+ end
44
58
  end
45
59
  end
@@ -15,9 +15,13 @@ module Typed
15
15
  sig { returns(Schema) }
16
16
  attr_reader :schema
17
17
 
18
+ sig { returns(T::Hash[T::Types::Base, T.untyped]) }
19
+ attr_reader :coercer_cache
20
+
18
21
  sig { params(schema: Schema).void }
19
22
  def initialize(schema:)
20
23
  @schema = schema
24
+ @coercer_cache = T.let({}, T::Hash[T::Types::Base, T.untyped])
21
25
  end
22
26
 
23
27
  sig { abstract.params(source: Input).returns(DeserializeResult) }
@@ -39,33 +43,37 @@ module Typed
39
43
  Success.new(Validations::ValidatedValue.new(name: field.name, value: field.default))
40
44
  elsif value.nil? || field.works_with?(value)
41
45
  field.validate(value)
42
- elsif field.type.class <= T::Types::Union
43
- errors = []
44
- validated_value = T.let(nil, T.nilable(Typed::Result[Typed::Validations::ValidatedValue, Typed::Validations::ValidationError]))
46
+ else
47
+ coercer_instance = fetch_coercer(field.type)
48
+ if !coercer_instance.nil?
49
+ result = coercer_instance.coerce(type: field.type, value:)
50
+ if result.success?
51
+ field.validate(result.payload)
52
+ else
53
+ Failure.new(Validations::ValidationError.new(result.error.message))
54
+ end
55
+ elsif field.type.class <= T::Types::Union
56
+ errors = []
57
+ validated_value = T.let(nil, T.nilable(Typed::Result[Typed::Validations::ValidatedValue, Typed::Validations::ValidationError]))
45
58
 
46
- T.cast(field.type, T::Types::Union).types.each do |sub_type|
47
- # the if clause took care of cases where value is nil so we can skip NilClass
48
- next if sub_type.raw_type.equal?(NilClass)
59
+ T.cast(field.type, T::Types::Union).types.each do |sub_type|
60
+ # the if clause took care of cases where value is nil so we can skip NilClass
61
+ next if sub_type.raw_type.equal?(NilClass)
49
62
 
50
- coercion_result = Coercion.coerce(type: sub_type, value: value)
63
+ coercion_result = Coercion.coerce(type: sub_type, value: value)
51
64
 
52
- if coercion_result.success?
53
- validated_value = field.validate(coercion_result.payload)
65
+ if coercion_result.success?
66
+ validated_value = field.validate(coercion_result.payload)
54
67
 
55
- break
56
- else
57
- errors << Validations::ValidationError.new(coercion_result.error.message)
68
+ break
69
+ else
70
+ errors << Validations::ValidationError.new(coercion_result.error.message)
71
+ end
58
72
  end
59
- end
60
73
 
61
- validated_value.nil? ? Failure.new(Validations::ValidationError.new(errors.map(&:message).join(", "))) : validated_value
62
- else
63
- coercion_result = Coercion.coerce(type: field.type, value:)
64
-
65
- if coercion_result.success?
66
- field.validate(coercion_result.payload)
74
+ validated_value.nil? ? Failure.new(Validations::ValidationError.new(errors.map(&:message).join(", "))) : validated_value
67
75
  else
68
- Failure.new(Validations::ValidationError.new(coercion_result.error.message))
76
+ Failure.new(Validations::ValidationError.new("Coercer not found for type #{field.type}."))
69
77
  end
70
78
  end
71
79
  end
@@ -88,5 +96,16 @@ module Typed
88
96
 
89
97
  hsh
90
98
  end
99
+
100
+ sig { params(type: T::Types::Base).returns(T.untyped) }
101
+ def fetch_coercer(type)
102
+ cached = coercer_cache[type]
103
+ return cached if cached
104
+
105
+ coercer_class = Coercion::CoercerRegistry.instance.select_coercer_by(type: type)
106
+ return nil if coercer_class.nil?
107
+
108
+ coercer_cache[type] = coercer_class.new
109
+ end
91
110
  end
92
111
  end