sorbet-schema 0.3.0 → 0.4.0

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