sorbet-schema 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 004ea246c450adc69f61c55875a4258a7353c9a5353084b20f3f927dd913a9fc
4
- data.tar.gz: d9375c481dda06ccb6af6955541993e44f5f1b1a249ab78c3c3624310d888796
3
+ metadata.gz: 9af17198e776435ac97075ce33b365c34fd539aa7998ca9f60f9eef1a57ddd95
4
+ data.tar.gz: 8afbc08bc51a6cdc849803273af0c44e9f8a86e04991d9cd70767e565b3c68ca
5
5
  SHA512:
6
- metadata.gz: c943356484fbc2f8d2bf9539d4432a1a9b3f9904b4e8663165bb152d22ac49548b9e50ff9af5031e74a9c734f1eb3dd3ca65b324d3b09af13c4835bf3a1e15db
7
- data.tar.gz: 73e261c571f2ad88ef04a7c552d4fa2d808a083e1306819323b13eddb0ec3506405c9690d59b4eab5efa37ac222cf15d2b4d08223ab88dcfc0cccfd18b9f7aff
6
+ metadata.gz: 260e1ee1603ef6ae6ddd5cc20544a874a097b65f95736e42dc97f489b979df5a6a41d48124d2a5f5c2643e9f0989de0e67ed7a7f787adabf39fd12168bc05b65
7
+ data.tar.gz: 94836f2ea97f2c4ac158562f2a6b9ffdd05d4ad2a0f34423e77d42b989c894caf08e6fdc28693491d8903d826aa3da860a4d85ceb14ba37b0a448542a41b51e7
data/CHANGELOG.md CHANGED
@@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.4.0](https://github.com/maxveldink/sorbet-schema/compare/v0.3.0...v0.4.0) (2024-03-14)
8
+
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+
12
+ * Have coercers take in a type instead of the full field
13
+ * Update Field's types to a support Sorbets T::Types::Base classes
14
+ * Changed serialize return value to a Result
15
+ * adds SerializationError ancestor
16
+
17
+ ### Features
18
+
19
+ * Add BooleanCoercer ([acd220f](https://github.com/maxveldink/sorbet-schema/commit/acd220f55fe0ebc823de6cc43776a1f510a4acd0))
20
+ * Add EnumCoercer ([5c0e2b5](https://github.com/maxveldink/sorbet-schema/commit/5c0e2b51990dfb72218129b0935f881622324194))
21
+ * Add from_hash and from_json helpers to Schemas ([#44](https://github.com/maxveldink/sorbet-schema/issues/44)) ([55c2da7](https://github.com/maxveldink/sorbet-schema/commit/55c2da77b7c2636339c684560bf15c51ff3ff4b1))
22
+ * Add idempotency to Struct coercer ([3a42957](https://github.com/maxveldink/sorbet-schema/commit/3a42957836afee55b074fc5c8a41eac6d31ada70))
23
+ * Add option to serialize values to HashSerializer ([710d365](https://github.com/maxveldink/sorbet-schema/commit/710d365d477bd6c6bff20929fcdcc1d1cc95bdb3))
24
+ * Adds TypedArray coercer ([795ddd9](https://github.com/maxveldink/sorbet-schema/commit/795ddd97f05502b154d4cb165878c1f78935cb3c))
25
+
26
+
27
+ ### Code Refactoring
28
+
29
+ * adds SerializationError ancestor ([f8ea753](https://github.com/maxveldink/sorbet-schema/commit/f8ea75304613cbab17f698006698a2524a44b538))
30
+ * Changed serialize return value to a Result ([948c678](https://github.com/maxveldink/sorbet-schema/commit/948c67815dab19793dd2f321a90797d123740e0e))
31
+ * Have coercers take in a type instead of the full field ([c06169e](https://github.com/maxveldink/sorbet-schema/commit/c06169e0fa1cf7c8f645ecabef19cc2f5facffe4))
32
+ * Update Field's types to a support Sorbets T::Types::Base classes ([9ef1cd5](https://github.com/maxveldink/sorbet-schema/commit/9ef1cd5caf09396d8dae6a4db1feeb4f88dd25e9))
33
+
7
34
  ## [0.3.0](https://github.com/maxveldink/sorbet-schema/compare/v0.2.2...v0.3.0) (2024-03-12)
8
35
 
9
36
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorbet-schema (0.3.0)
4
+ sorbet-schema (0.4.0)
5
5
  sorbet-result (~> 1.1)
6
6
  sorbet-runtime (~> 0.5)
7
7
  sorbet-struct-comparable (~> 1.3)
@@ -6,17 +6,42 @@
6
6
  class HashTransformer
7
7
  extend T::Sig
8
8
 
9
+ sig { params(should_serialize_values: T::Boolean).void }
10
+ def initialize(should_serialize_values: false)
11
+ @should_serialize_values = should_serialize_values
12
+ end
13
+
9
14
  sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
10
15
  def deep_symbolize_keys(hash)
11
16
  hash.each_with_object({}) do |(key, value), result|
12
- result[key.to_sym] = value.is_a?(Hash) ? deep_symbolize_keys(value) : value
17
+ result[key.to_sym] = transform_value(value, hash_transformation_method: :deep_symbolize_keys)
13
18
  end
14
19
  end
15
20
 
16
21
  sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[String, T.untyped]) }
17
22
  def deep_stringify_keys(hash)
18
23
  hash.each_with_object({}) do |(key, value), result|
19
- result[key.to_s] = value.is_a?(Hash) ? deep_stringify_keys(value) : value
24
+ result[key.to_s] = transform_value(value, hash_transformation_method: :deep_stringify_keys)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ sig { returns(T::Boolean) }
31
+ attr_reader :should_serialize_values
32
+
33
+ sig { params(value: T.untyped, hash_transformation_method: Symbol).returns(T.untyped) }
34
+ def transform_value(value, hash_transformation_method:)
35
+ if value.is_a?(Hash)
36
+ send(hash_transformation_method, value)
37
+ elsif value.is_a?(Array)
38
+ value.map { |inner_val| transform_value(inner_val, hash_transformation_method: hash_transformation_method) }
39
+ elsif value.is_a?(T::Struct) && should_serialize_values
40
+ deep_symbolize_keys(value.serialize)
41
+ elsif value.respond_to?(:serialize) && should_serialize_values
42
+ value.serialize
43
+ else
44
+ value
20
45
  end
21
46
  end
22
47
  end
@@ -1,5 +1,5 @@
1
1
  # typed: strict
2
2
 
3
3
  module SorbetSchema
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -0,0 +1,31 @@
1
+ # typed: strict
2
+
3
+ module Typed
4
+ module Coercion
5
+ class BooleanCoercer < Coercer
6
+ extend T::Generic
7
+
8
+ Target = type_member { {fixed: T::Boolean} }
9
+
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type == T::Utils.coerce(T::Boolean)
13
+ end
14
+
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
+ if T.cast(type, T::Types::Base).recursively_valid?(value)
18
+ Success.new(value)
19
+ elsif value == "true"
20
+ Success.new(true)
21
+ elsif value == "false"
22
+ Success.new(false)
23
+ else
24
+ Failure.new(CoercionError.new)
25
+ end
26
+ rescue TypeError
27
+ Failure.new(CoercionError.new("Field type must be a T::Boolean."))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -10,12 +10,12 @@ module Typed
10
10
 
11
11
  Target = type_member(:out)
12
12
 
13
- sig { abstract.params(type: T::Class[T.anything]).returns(T::Boolean) }
13
+ sig { abstract.params(type: Field::Type).returns(T::Boolean) }
14
14
  def used_for_type?(type)
15
15
  end
16
16
 
17
- sig { abstract.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
18
- def coerce(field:, value:)
17
+ sig { abstract.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
18
+ def coerce(type:, value:)
19
19
  end
20
20
  end
21
21
  end
@@ -11,7 +11,18 @@ module Typed
11
11
 
12
12
  Registry = T.type_alias { T::Array[T.class_of(Coercer)] }
13
13
 
14
- DEFAULT_COERCERS = T.let([StringCoercer, IntegerCoercer, FloatCoercer, StructCoercer], Registry)
14
+ DEFAULT_COERCERS = T.let(
15
+ [
16
+ StringCoercer,
17
+ BooleanCoercer,
18
+ IntegerCoercer,
19
+ FloatCoercer,
20
+ EnumCoercer,
21
+ StructCoercer,
22
+ TypedArrayCoercer
23
+ ],
24
+ Registry
25
+ )
15
26
 
16
27
  sig { void }
17
28
  def initialize
@@ -28,7 +39,7 @@ module Typed
28
39
  @available = DEFAULT_COERCERS.clone
29
40
  end
30
41
 
31
- sig { params(type: T::Class[T.anything]).returns(T.nilable(T.class_of(Coercer))) }
42
+ sig { params(type: Field::Type).returns(T.nilable(T.class_of(Coercer))) }
32
43
  def select_coercer_by(type:)
33
44
  @available.find { |coercer| coercer.new.used_for_type?(type) }
34
45
  end
@@ -0,0 +1,25 @@
1
+ # typed: strict
2
+
3
+ module Typed
4
+ module Coercion
5
+ class EnumCoercer < Coercer
6
+ extend T::Generic
7
+
8
+ Target = type_member { {fixed: T::Enum} }
9
+
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type.is_a?(Class) && !!(type < T::Enum)
13
+ end
14
+
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
+ return Failure.new(CoercionError.new("Field type must inherit from T::Enum for Enum coercion.")) unless type.is_a?(Class) && !!(type < T::Enum)
18
+
19
+ Success.new(type.from_serialized(value))
20
+ rescue KeyError => e
21
+ Failure.new(CoercionError.new(e.message))
22
+ end
23
+ end
24
+ end
25
+ end
@@ -7,13 +7,13 @@ module Typed
7
7
 
8
8
  Target = type_member { {fixed: Float} }
9
9
 
10
- sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
11
  def used_for_type?(type)
12
- type == Float
12
+ T::Utils.coerce(type) == T::Utils.coerce(Float)
13
13
  end
14
14
 
15
- sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
16
- def coerce(field:, value:)
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
17
  Success.new(Float(value))
18
18
  rescue ArgumentError, TypeError
19
19
  Failure.new(CoercionError.new("'#{value}' cannot be coerced into Float."))
@@ -7,13 +7,13 @@ module Typed
7
7
 
8
8
  Target = type_member { {fixed: Integer} }
9
9
 
10
- sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
11
  def used_for_type?(type)
12
12
  type == Integer
13
13
  end
14
14
 
15
- sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
16
- def coerce(field:, value:)
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
17
  Success.new(Integer(value))
18
18
  rescue ArgumentError, TypeError
19
19
  Failure.new(CoercionError.new("'#{value}' cannot be coerced into Integer."))
@@ -7,13 +7,13 @@ module Typed
7
7
 
8
8
  Target = type_member { {fixed: String} }
9
9
 
10
- sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
11
  def used_for_type?(type)
12
12
  type == String
13
13
  end
14
14
 
15
- sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
16
- def coerce(field:, value:)
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
17
  Success.new(String(value))
18
18
  end
19
19
  end
@@ -7,17 +7,17 @@ module Typed
7
7
 
8
8
  Target = type_member { {fixed: T::Struct} }
9
9
 
10
- sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
11
  def used_for_type?(type)
12
- !!(type < T::Struct)
12
+ type.is_a?(Class) && !!(type < T::Struct)
13
13
  end
14
14
 
15
- sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
16
- def coerce(field:, value:)
17
- type = field.type
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
+ return Failure.new(CoercionError.new("Field type must inherit from T::Struct for Struct coercion.")) unless type.is_a?(Class) && type < T::Struct
18
+ return Success.new(value) if value.instance_of?(type)
18
19
 
19
- return Failure.new(CoercionError.new("Field type must inherit from T::Struct for Struct coercion.")) unless type < T::Struct
20
- return Failure.new(CoercionError.new("Value must be a Hash for Struct coercion.")) unless value.is_a?(Hash)
20
+ return Failure.new(CoercionError.new("Value of type '#{value.class}' cannot be coerced to #{type} Struct.")) unless value.is_a?(Hash)
21
21
 
22
22
  Success.new(type.from_hash!(HashTransformer.new.deep_stringify_keys(value)))
23
23
  rescue ArgumentError => e
@@ -0,0 +1,34 @@
1
+ # typed: strict
2
+
3
+ module Typed
4
+ module Coercion
5
+ class TypedArrayCoercer < Coercer
6
+ extend T::Generic
7
+
8
+ Target = type_member { {fixed: T::Array[T.untyped]} }
9
+
10
+ sig { override.params(type: Field::Type).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type.is_a?(T::Types::TypedArray)
13
+ end
14
+
15
+ sig { override.params(type: Field::Type, value: Value).returns(Result[Target, CoercionError]) }
16
+ def coerce(type:, value:)
17
+ return Failure.new(CoercionError.new("Field type must be a T::Array.")) unless type.is_a?(T::Types::TypedArray)
18
+ return Failure.new(CoercionError.new("Value must be an Array.")) unless value.is_a?(Array)
19
+
20
+ return Success.new(value) if type.recursively_valid?(value)
21
+
22
+ coerced_results = value.map do |item|
23
+ Coercion.coerce(type: type.type.raw_type, value: item)
24
+ end
25
+
26
+ if coerced_results.all?(&:success?)
27
+ Success.new(coerced_results.map(&:payload))
28
+ else
29
+ Failure.new(CoercionError.new(coerced_results.select(&:failure?).map(&:error).map(&:message).join(" | ")))
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -9,13 +9,13 @@ module Typed
9
9
  CoercerRegistry.instance.register(coercer)
10
10
  end
11
11
 
12
- sig { type_parameters(:U).params(field: Field, value: Value).returns(Result[Value, CoercionError]) }
13
- def self.coerce(field:, value:)
14
- coercer = CoercerRegistry.instance.select_coercer_by(type: field.type)
12
+ sig { type_parameters(:U).params(type: Field::Type, value: Value).returns(Result[Value, CoercionError]) }
13
+ def self.coerce(type:, value:)
14
+ coercer = CoercerRegistry.instance.select_coercer_by(type: type)
15
15
 
16
16
  return Failure.new(CoercionNotSupportedError.new) unless coercer
17
17
 
18
- coercer.new.coerce(field: field, value: value)
18
+ coercer.new.coerce(type: type, value: value)
19
19
  end
20
20
  end
21
21
  end
@@ -1,7 +1,7 @@
1
1
  # typed: strict
2
2
 
3
3
  module Typed
4
- class DeserializeError < StandardError
4
+ class DeserializeError < SerializationError
5
5
  extend T::Sig
6
6
 
7
7
  sig { returns({error: String}) }
data/lib/typed/field.rb CHANGED
@@ -6,8 +6,10 @@ module Typed
6
6
 
7
7
  include ActsAsComparable
8
8
 
9
+ Type = T.type_alias { T.any(T::Class[T.anything], T::Types::Base) }
10
+
9
11
  const :name, Symbol
10
- const :type, T::Class[T.anything]
12
+ const :type, Type
11
13
  const :required, T::Boolean, default: true
12
14
 
13
15
  sig { returns(T::Boolean) }
@@ -24,5 +26,12 @@ module Typed
24
26
  def validate(value)
25
27
  Validations::FieldTypeValidator.new.validate(field: self, value: value)
26
28
  end
29
+
30
+ sig { params(value: Value).returns(T::Boolean) }
31
+ def works_with?(value)
32
+ value.class == type || T.cast(type, T::Types::Base).recursively_valid?(value) # standard:disable Style/ClassEqualityComparison
33
+ rescue TypeError
34
+ false
35
+ end
27
36
  end
28
37
  end
@@ -3,19 +3,33 @@
3
3
  module Typed
4
4
  class HashSerializer < Serializer
5
5
  InputHash = T.type_alias { T::Hash[T.any(Symbol, String), T.untyped] }
6
- OutputHash = T.type_alias { Params }
7
-
8
6
  Input = type_member { {fixed: InputHash} }
9
- Output = type_member { {fixed: OutputHash} }
7
+ Output = type_member { {fixed: Params} }
8
+
9
+ sig { params(schema: Schema, should_serialize_values: T::Boolean).void }
10
+ def initialize(schema:, should_serialize_values: false)
11
+ @should_serialize_values = should_serialize_values
12
+
13
+ super(schema: schema)
14
+ end
10
15
 
11
16
  sig { override.params(source: Input).returns(Result[T::Struct, DeserializeError]) }
12
17
  def deserialize(source)
13
- deserialize_from_creation_params(HashTransformer.new.deep_symbolize_keys(source))
18
+ deserialize_from_creation_params(HashTransformer.new(should_serialize_values: should_serialize_values).deep_symbolize_keys(source))
14
19
  end
15
20
 
16
- sig { override.params(struct: T::Struct).returns(Output) }
21
+ sig { override.params(struct: T::Struct).returns(Result[Output, SerializeError]) }
17
22
  def serialize(struct)
18
- HashTransformer.new.deep_symbolize_keys(struct.serialize)
23
+ return Failure.new(SerializeError.new("'#{struct.class}' cannot be serialized to target type of '#{schema.target}'.")) if struct.class != schema.target
24
+
25
+ hsh = schema.fields.each_with_object({}) { |field, hsh| hsh[field.name] = struct.send(field.name) }
26
+
27
+ Success.new(HashTransformer.new(should_serialize_values: should_serialize_values).deep_symbolize_keys(hsh.compact))
19
28
  end
29
+
30
+ private
31
+
32
+ sig { returns(T::Boolean) }
33
+ attr_reader :should_serialize_values
20
34
  end
21
35
  end
@@ -20,9 +20,11 @@ module Typed
20
20
  Failure.new(ParseError.new(format: :json))
21
21
  end
22
22
 
23
- sig { override.params(struct: T::Struct).returns(Output) }
23
+ sig { override.params(struct: T::Struct).returns(Result[Output, SerializeError]) }
24
24
  def serialize(struct)
25
- JSON.generate(struct.serialize)
25
+ return Failure.new(SerializeError.new("'#{struct.class}' cannot be serialized to target type of '#{schema.target}'.")) if struct.class != schema.target
26
+
27
+ Success.new(JSON.generate(struct.serialize))
26
28
  end
27
29
  end
28
30
  end
data/lib/typed/schema.rb CHANGED
@@ -17,5 +17,15 @@ module Typed
17
17
  end
18
18
  )
19
19
  end
20
+
21
+ sig { params(hash: Typed::HashSerializer::InputHash).returns(Typed::Serializer::DeserializeResult) }
22
+ def from_hash(hash)
23
+ Typed::HashSerializer.new(schema: self).deserialize(hash)
24
+ end
25
+
26
+ sig { params(json: String).returns(Typed::Serializer::DeserializeResult) }
27
+ def from_json(json)
28
+ Typed::JSONSerializer.new(schema: self).deserialize(json)
29
+ end
20
30
  end
21
31
  end
@@ -0,0 +1,17 @@
1
+ # typed: strict
2
+
3
+ module Typed
4
+ class SerializationError < StandardError
5
+ extend T::Sig
6
+
7
+ sig { returns({error: String}) }
8
+ def to_h
9
+ {error: message}
10
+ end
11
+
12
+ sig { params(_options: T::Hash[T.untyped, T.untyped]).returns(String) }
13
+ def to_json(_options = {})
14
+ JSON.generate(to_h)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ # typed: strict
2
+
3
+ module Typed
4
+ class SerializeError < SerializationError
5
+ end
6
+ end
@@ -20,11 +20,11 @@ module Typed
20
20
  @schema = schema
21
21
  end
22
22
 
23
- sig { abstract.params(source: Output).returns(DeserializeResult) }
23
+ sig { abstract.params(source: Input).returns(DeserializeResult) }
24
24
  def deserialize(source)
25
25
  end
26
26
 
27
- sig { abstract.params(struct: T::Struct).returns(Output) }
27
+ sig { abstract.params(struct: T::Struct).returns(Result[Output, SerializeError]) }
28
28
  def serialize(struct)
29
29
  end
30
30
 
@@ -35,18 +35,16 @@ module Typed
35
35
  results = schema.fields.map do |field|
36
36
  value = creation_params[field.name]
37
37
 
38
- if value.nil?
38
+ if value.nil? || field.works_with?(value)
39
39
  field.validate(value)
40
- elsif value.class != field.type
41
- coercion_result = Coercion.coerce(field: field, value: value)
40
+ else
41
+ coercion_result = Coercion.coerce(type: field.type, value: value)
42
42
 
43
43
  if coercion_result.success?
44
44
  field.validate(coercion_result.payload)
45
45
  else
46
46
  Failure.new(Validations::ValidationError.new(coercion_result.error.message))
47
47
  end
48
- else
49
- field.validate(value)
50
48
  end
51
49
  end
52
50
 
@@ -9,7 +9,7 @@ module Typed
9
9
 
10
10
  sig { override.params(field: Field, value: Value).returns(ValidationResult) }
11
11
  def validate(field:, value:)
12
- if field.type == value.class
12
+ if field.works_with?(value)
13
13
  Success.new(ValidatedValue.new(name: field.name, value: value))
14
14
  elsif field.required? && value.nil?
15
15
  Failure.new(RequiredFieldError.new(field_name: field.name))
@@ -5,7 +5,7 @@ module Typed
5
5
  class TypeMismatchError < ValidationError
6
6
  extend T::Sig
7
7
 
8
- sig { params(field_name: Symbol, field_type: T::Class[T.anything], given_type: T::Class[T.anything]).void }
8
+ sig { params(field_name: Symbol, field_type: Field::Type, given_type: T::Class[T.anything]).void }
9
9
  def initialize(field_name:, field_type:, given_type:)
10
10
  super("Invalid type given to #{field_name}. Expected #{field_type}, got #{given_type}.")
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max VelDink
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-12 00:00:00.000000000 Z
11
+ date: 2024-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-result
@@ -87,20 +87,25 @@ files:
87
87
  - lib/sorbet-schema/hash_transformer.rb
88
88
  - lib/sorbet-schema/version.rb
89
89
  - lib/typed/coercion.rb
90
+ - lib/typed/coercion/boolean_coercer.rb
90
91
  - lib/typed/coercion/coercer.rb
91
92
  - lib/typed/coercion/coercer_registry.rb
92
93
  - lib/typed/coercion/coercion_error.rb
93
94
  - lib/typed/coercion/coercion_not_supported_error.rb
95
+ - lib/typed/coercion/enum_coercer.rb
94
96
  - lib/typed/coercion/float_coercer.rb
95
97
  - lib/typed/coercion/integer_coercer.rb
96
98
  - lib/typed/coercion/string_coercer.rb
97
99
  - lib/typed/coercion/struct_coercer.rb
100
+ - lib/typed/coercion/typed_array_coercer.rb
98
101
  - lib/typed/deserialize_error.rb
99
102
  - lib/typed/field.rb
100
103
  - lib/typed/hash_serializer.rb
101
104
  - lib/typed/json_serializer.rb
102
105
  - lib/typed/parse_error.rb
103
106
  - lib/typed/schema.rb
107
+ - lib/typed/serialization_error.rb
108
+ - lib/typed/serialize_error.rb
104
109
  - lib/typed/serializer.rb
105
110
  - lib/typed/validations.rb
106
111
  - lib/typed/validations/field_type_validator.rb