sorbet-schema 0.1.1 → 0.2.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: a84e583349600c869258e039e2e77f14dad713fb1c3a8d60c8759d962ff4eaef
4
- data.tar.gz: 67658459bd944e7118b45cb2fcfd5abbaea9c212153edec253d5d329519d772c
3
+ metadata.gz: 1d70fa44a21277553c70f83ca5bb33d012f165f4ce39921374bad60f4aafaead
4
+ data.tar.gz: ed9f24ad2785da98b16306587556c165e6218134540ce28ef22a422852a4fa3f
5
5
  SHA512:
6
- metadata.gz: 8ac735414ed3ed8668384f68d49c666abf8426410adabcdae115d533dd9110f4cdda2eaf5bc8c85f60797101a8d1dc3723b9fd52740144f639ff390abded0719
7
- data.tar.gz: fd4877530222a722f9a3e719bb592d06ae9d6b979b5b22aac7638a80a678779e0d9408a014ed857cba938fe3e0410d6af1f542c865b843462427e6b2467c3813
6
+ metadata.gz: 9faa04758b3bca54e9c83024dcc30f94dcd84f6f4260bdff0f9e80a6e5ddd134626192264dbfc65df8bab1a5af0cdde9e65dd3f5d7f33ee1a0eb373729d007d5
7
+ data.tar.gz: '0649efc2845a54f4cfde1fc3adfc1330bc18dc06b22b501f0ce02d178af893228a81dc7a50373b771b230b15c42d97b35c50820b3fca9f49dbbd81667c22c78f'
data/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ 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.2.0](https://github.com/maxveldink/sorbet-schema/compare/v0.1.1...v0.2.0) (2024-03-08)
8
+
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+
12
+ * Allow for custom Coercers ([#34](https://github.com/maxveldink/sorbet-schema/issues/34))
13
+
14
+ ### Features
15
+
16
+ * Allow for custom Coercers ([#34](https://github.com/maxveldink/sorbet-schema/issues/34)) ([54c6a53](https://github.com/maxveldink/sorbet-schema/commit/54c6a53019b18d65b18d6d1130c1034f1f6b1341))
17
+
7
18
  ## [0.1.1](https://github.com/maxveldink/sorbet-schema/compare/v0.1.0...v0.1.1) (2024-03-08)
8
19
 
9
20
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorbet-schema (0.1.1)
4
+ sorbet-schema (0.2.0)
5
5
  sorbet-result (~> 1.1)
6
6
  sorbet-runtime (~> 0.5)
7
7
  sorbet-struct-comparable (~> 1.3)
@@ -1,5 +1,5 @@
1
1
  # typed: strict
2
2
 
3
3
  module SorbetSchema
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Typed
4
4
  module Coercion
5
- module Coercer
5
+ class Coercer
6
6
  extend T::Sig
7
7
  extend T::Generic
8
8
 
@@ -10,6 +10,10 @@ module Typed
10
10
 
11
11
  Target = type_member(:out)
12
12
 
13
+ sig { abstract.params(type: T::Class[T.anything]).returns(T::Boolean) }
14
+ def used_for_type?(type)
15
+ end
16
+
13
17
  sig { abstract.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
14
18
  def coerce(field:, value:)
15
19
  end
@@ -0,0 +1,37 @@
1
+ # typed: strict
2
+
3
+ require "singleton"
4
+
5
+ module Typed
6
+ module Coercion
7
+ class CoercerRegistry
8
+ extend T::Sig
9
+
10
+ include Singleton
11
+
12
+ Registry = T.type_alias { T::Array[T.class_of(Coercer)] }
13
+
14
+ DEFAULT_COERCERS = T.let([StringCoercer, IntegerCoercer, FloatCoercer, StructCoercer], Registry)
15
+
16
+ sig { void }
17
+ def initialize
18
+ @available = T.let(DEFAULT_COERCERS.clone, Registry)
19
+ end
20
+
21
+ sig { params(coercer: T.class_of(Coercer)).void }
22
+ def register(coercer)
23
+ @available.prepend(coercer)
24
+ end
25
+
26
+ sig { void }
27
+ def reset!
28
+ @available = DEFAULT_COERCERS.clone
29
+ end
30
+
31
+ sig { params(type: T::Class[T.anything]).returns(T.nilable(T.class_of(Coercer))) }
32
+ def select_coercer_by(type:)
33
+ @available.find { |coercer| coercer.new.used_for_type?(type) }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -2,16 +2,18 @@
2
2
 
3
3
  module Typed
4
4
  module Coercion
5
- class FloatCoercer
6
- extend T::Sig
5
+ class FloatCoercer < Coercer
7
6
  extend T::Generic
8
7
 
9
- extend Coercer
8
+ Target = type_member { {fixed: Float} }
10
9
 
11
- Target = type_template { {fixed: Float} }
10
+ sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type == Float
13
+ end
12
14
 
13
15
  sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
14
- def self.coerce(field:, value:)
16
+ def coerce(field:, value:)
15
17
  Success.new(Float(value))
16
18
  rescue ArgumentError, TypeError
17
19
  Failure.new(CoercionError.new("'#{value}' cannot be coerced into Float."))
@@ -2,16 +2,18 @@
2
2
 
3
3
  module Typed
4
4
  module Coercion
5
- class IntegerCoercer
6
- extend T::Sig
5
+ class IntegerCoercer < Coercer
7
6
  extend T::Generic
8
7
 
9
- extend Coercer
8
+ Target = type_member { {fixed: Integer} }
10
9
 
11
- Target = type_template { {fixed: Integer} }
10
+ sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type == Integer
13
+ end
12
14
 
13
15
  sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
14
- def self.coerce(field:, value:)
16
+ def coerce(field:, value:)
15
17
  Success.new(Integer(value))
16
18
  rescue ArgumentError, TypeError
17
19
  Failure.new(CoercionError.new("'#{value}' cannot be coerced into Integer."))
@@ -2,16 +2,18 @@
2
2
 
3
3
  module Typed
4
4
  module Coercion
5
- class StringCoercer
6
- extend T::Sig
5
+ class StringCoercer < Coercer
7
6
  extend T::Generic
8
7
 
9
- extend Coercer
8
+ Target = type_member { {fixed: String} }
10
9
 
11
- Target = type_template { {fixed: String} }
10
+ sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ type == String
13
+ end
12
14
 
13
15
  sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
14
- def self.coerce(field:, value:)
16
+ def coerce(field:, value:)
15
17
  Success.new(String(value))
16
18
  end
17
19
  end
@@ -2,16 +2,18 @@
2
2
 
3
3
  module Typed
4
4
  module Coercion
5
- class StructCoercer
6
- extend T::Sig
5
+ class StructCoercer < Coercer
7
6
  extend T::Generic
8
7
 
9
- extend Coercer
8
+ Target = type_member { {fixed: T::Struct} }
10
9
 
11
- Target = type_template { {fixed: T::Struct} }
10
+ sig { override.params(type: T::Class[T.anything]).returns(T::Boolean) }
11
+ def used_for_type?(type)
12
+ !!(type < T::Struct)
13
+ end
12
14
 
13
15
  sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
14
- def self.coerce(field:, value:)
16
+ def coerce(field:, value:)
15
17
  type = field.type
16
18
 
17
19
  return Failure.new(CoercionError.new("Field type must inherit from T::Struct for Struct coercion.")) unless type < T::Struct
@@ -4,23 +4,18 @@ module Typed
4
4
  module Coercion
5
5
  extend T::Sig
6
6
 
7
- # TODO: We can definitely improve how we select which coercer to use
8
- # Related issues:
9
- # * https://github.com/maxveldink/sorbet-schema/issues/9
10
- # * https://github.com/maxveldink/sorbet-schema/issues/10
7
+ sig { params(coercer: T.class_of(Coercer)).void }
8
+ def self.register_coercer(coercer)
9
+ CoercerRegistry.instance.register(coercer)
10
+ end
11
+
11
12
  sig { type_parameters(:U).params(field: Field, value: Value).returns(Result[Value, CoercionError]) }
12
13
  def self.coerce(field:, value:)
13
- if field.type < T::Struct
14
- StructCoercer.coerce(field: field, value: value)
15
- elsif field.type == String
16
- StringCoercer.coerce(field: field, value: value)
17
- elsif field.type == Integer
18
- IntegerCoercer.coerce(field: field, value: value)
19
- elsif field.type == Float
20
- FloatCoercer.coerce(field: field, value: value)
21
- else
22
- Failure.new(CoercionNotSupportedError.new)
23
- end
14
+ coercer = CoercerRegistry.instance.select_coercer_by(type: field.type)
15
+
16
+ return Failure.new(CoercionNotSupportedError.new) unless coercer
17
+
18
+ coercer.new.coerce(field: field, value: value)
24
19
  end
25
20
  end
26
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max VelDink
@@ -89,6 +89,7 @@ files:
89
89
  - lib/sorbet-schema/version.rb
90
90
  - lib/typed/coercion.rb
91
91
  - lib/typed/coercion/coercer.rb
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
94
95
  - lib/typed/coercion/float_coercer.rb