sorbet-coerce 0.2.6 → 0.2.7

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: 61b6f639daa4889060a9540e4fd31f7fbfe19529dac7246a91dc4ea9355b9d70
4
- data.tar.gz: 7d0ec3164d26cbf16bc45e94820f02142197191e3cc7ae4db7e8c21db351a0f3
3
+ metadata.gz: 017a474302bad34d6523e0140f0a221419874ddb6488f5cde3075458c54a245e
4
+ data.tar.gz: '0822f50c595a31bd377ff359d7e05f42ef60a2c4a9dd46915527dcf47c344081'
5
5
  SHA512:
6
- metadata.gz: d2ce360c7fd4474d57e3fc5b1115d3711ae41b177a60dcc2f07239f602aab45ab2a6a0ba429df9d7d2edc7df4689cac4f76d3b363ebd055b5b9a53be551e6e83
7
- data.tar.gz: 3a3af86be35e961882e11a326e4609376eb3a2fd6a30658be044559fad9b56feabeeae226b91fb85f6b515304a9f982d40e1aaebc9b3a462c076031c1418dfd4
6
+ metadata.gz: e105f8b039d77562b9a03ed58cc55cebb2e55a526917d1965c2fce7e410869d8bb9ea1d94e50f8086d298bf818eb63b5fb6293326e073621f6dc66450d6632c8
7
+ data.tar.gz: 2c0be667253b77c2e84930cf1fa526b01ed79c3cb603b708e2256958d3def7679adb275cbeccee3f5e7e6649408445c43d3bb6892281fe42efaa511464963fbc
@@ -1,23 +1,8 @@
1
- # typed: strict
2
- require 'sorbet-coerce/configuration'
1
+ # typed: ignore
3
2
  require 'sorbet-coerce/converter'
4
- require 'safe_type'
5
3
 
6
4
  module TypeCoerce
7
- class CoercionError < SafeType::CoercionError; end
8
- class ShapeError < SafeType::CoercionError; end
9
-
10
- define_singleton_method(:[]) do |type|
11
- Class.new(TypeCoerce::Private::Converter) do
12
- define_method(:to_s) { "#{name}#[#{type.to_s}]" }
13
-
14
- define_method(:from) do |args, raise_coercion_error: nil|
15
- if raise_coercion_error.nil?
16
- raise_coercion_error = TypeCoerce::Configuration.raise_coercion_error
17
- end
18
-
19
- T.send('let', send('_convert', args, type, raise_coercion_error), type)
20
- end
21
- end
5
+ def self.[](type)
6
+ TypeCoerce::Converter.new(type)
22
7
  end
23
8
  end
@@ -1,153 +1,169 @@
1
- # typed: strict
1
+ # typed: ignore
2
+ require 'polyfill'
2
3
  require 'safe_type'
3
4
  require 'set'
4
5
  require 'sorbet-runtime'
5
- require 'polyfill'
6
+ require 'sorbet-coerce/configuration'
6
7
 
7
8
  using Polyfill(Hash: %w[#slice])
8
9
 
9
- module TypeCoerce; end
10
-
11
- module TypeCoerce::Private
12
- class Converter
13
- extend T::Sig
14
-
15
- PRIMITIVE_TYPES = T.let(::Set[
16
- Date,
17
- DateTime,
18
- Float,
19
- Integer,
20
- String,
21
- Symbol,
22
- Time,
23
- ], T.untyped)
24
-
25
- protected
26
- sig { params(value: T.untyped, type: T.untyped, raise_coercion_error: T::Boolean).returns(T.untyped) }
27
- def _convert(value, type, raise_coercion_error)
28
- if type.is_a?(T::Types::Untyped)
29
- value
30
- elsif type.is_a?(T::Types::TypedArray)
31
- _convert_to_a(value, type.type, raise_coercion_error)
32
- elsif type.is_a?(T::Types::TypedSet)
33
- Set.new(_convert_to_a(value, type.type, raise_coercion_error))
34
- elsif type.is_a?(T::Types::Simple)
35
- _convert(value, type.raw_type, raise_coercion_error)
36
- elsif type.is_a?(T::Types::Union)
37
- true_idx = T.let(nil, T.nilable(Integer))
38
- false_idx = T.let(nil, T.nilable(Integer))
39
- nil_idx = T.let(nil, T.nilable(Integer))
40
-
41
- type.types.each_with_index do |t, i|
42
- nil_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == NilClass
43
- true_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == TrueClass
44
- false_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == FalseClass
45
- end
46
-
47
- raise ArgumentError.new(
48
- 'the only supported union types are T.nilable and T::Boolean',
49
- ) unless (
50
- (!true_idx.nil? && !false_idx.nil? && !nil_idx.nil?) || # T.nilable(T::Boolean)
51
- (type.types.length == 2 && (
52
- !nil_idx.nil? || (!true_idx.nil? && !false_idx.nil?) # T.nilable || T::Boolean
53
- ))
54
- )
55
-
56
- if !true_idx.nil? && !false_idx.nil?
57
- _convert_simple(value, T::Boolean, raise_coercion_error)
58
- else
59
- _convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error)
60
- end
61
- elsif type.is_a?(T::Types::TypedHash)
62
- return {} if _nil_like?(value, type)
63
-
64
- unless value.respond_to?(:map)
65
- raise TypeCoerce::ShapeError.new(value, type)
66
- end
67
-
68
- value.map do |k, v|
69
- [
70
- _convert(k, type.keys, raise_coercion_error),
71
- _convert(v, type.values, raise_coercion_error),
72
- ]
73
- end.to_h
74
- elsif Object.const_defined?('T::Private::Types::TypeAlias') &&
75
- type.is_a?(T::Private::Types::TypeAlias)
76
- _convert(value, type.aliased_type, raise_coercion_error)
77
- elsif type.respond_to?(:<) && type < T::Struct
78
- return value if value.is_a?(type)
79
-
80
- args = _build_args(value, type, raise_coercion_error)
81
- type.new(args)
82
- else
83
- return value if value.is_a?(type)
10
+ module TypeCoerce
11
+ class CoercionError < SafeType::CoercionError; end
12
+ class ShapeError < SafeType::CoercionError; end
13
+ end
84
14
 
85
- _convert_simple(value, type, raise_coercion_error)
86
- end
87
- end
15
+ class TypeCoerce::Converter
16
+ def initialize(type)
17
+ @type = type
18
+ end
88
19
 
89
- sig { params(value: T.untyped, type: T.untyped, raise_coercion_error: T::Boolean).returns(T.untyped) }
90
- def _convert_simple(value, type, raise_coercion_error)
91
- return nil if _nil_like?(value, type)
20
+ def new
21
+ self
22
+ end
92
23
 
93
- safe_type_rule = T.let(nil, T.untyped)
24
+ def to_s
25
+ "#{name}#[#{@type.to_s}]"
26
+ end
94
27
 
95
- if type == T::Boolean
96
- safe_type_rule = SafeType::Boolean.strict
97
- elsif value.is_a?(type)
98
- return value
99
- elsif PRIMITIVE_TYPES.include?(type)
100
- safe_type_rule = SafeType.const_get(type.name).strict
101
- else
102
- safe_type_rule = type
28
+ def from(args, raise_coercion_error: nil)
29
+ if raise_coercion_error.nil?
30
+ raise_coercion_error = TypeCoerce::Configuration.raise_coercion_error
31
+ end
32
+
33
+ T.let(_convert(args, @type, raise_coercion_error), @type)
34
+ end
35
+
36
+ private
37
+
38
+ PRIMITIVE_TYPES = T.let(::Set[
39
+ Date,
40
+ DateTime,
41
+ Float,
42
+ Integer,
43
+ String,
44
+ Symbol,
45
+ Time,
46
+ ], T.untyped)
47
+
48
+ def _convert(value, type, raise_coercion_error)
49
+ if type.is_a?(T::Types::Untyped)
50
+ value
51
+ elsif type.is_a?(T::Types::TypedArray)
52
+ _convert_to_a(value, type.type, raise_coercion_error)
53
+ elsif type.is_a?(T::Types::TypedSet)
54
+ Set.new(_convert_to_a(value, type.type, raise_coercion_error))
55
+ elsif type.is_a?(T::Types::Simple)
56
+ _convert(value, type.raw_type, raise_coercion_error)
57
+ elsif type.is_a?(T::Types::Union)
58
+ true_idx = T.let(nil, T.nilable(Integer))
59
+ false_idx = T.let(nil, T.nilable(Integer))
60
+ nil_idx = T.let(nil, T.nilable(Integer))
61
+
62
+ type.types.each_with_index do |t, i|
63
+ nil_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == NilClass
64
+ true_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == TrueClass
65
+ false_idx = i if t.is_a?(T::Types::Simple) && t.raw_type == FalseClass
103
66
  end
104
67
 
105
- if safe_type_rule.is_a?(SafeType::Rule)
106
- SafeType::coerce(value, safe_type_rule)
68
+ raise ArgumentError.new(
69
+ 'the only supported union types are T.nilable and T::Boolean',
70
+ ) unless (
71
+ (!true_idx.nil? && !false_idx.nil? && !nil_idx.nil?) || # T.nilable(T::Boolean)
72
+ (type.types.length == 2 && (
73
+ !nil_idx.nil? || (!true_idx.nil? && !false_idx.nil?) # T.nilable || T::Boolean
74
+ ))
75
+ )
76
+
77
+ if !true_idx.nil? && !false_idx.nil?
78
+ _convert_simple(value, T::Boolean, raise_coercion_error)
107
79
  else
108
- type.new(value)
80
+ _convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error)
109
81
  end
110
- rescue SafeType::EmptyValueError, SafeType::CoercionError
111
- if raise_coercion_error
112
- raise TypeCoerce::CoercionError.new(value, type)
113
- else
114
- nil
82
+ elsif type.is_a?(T::Types::TypedHash)
83
+ return {} if _nil_like?(value, type)
84
+
85
+ unless value.respond_to?(:map)
86
+ raise TypeCoerce::ShapeError.new(value, type)
115
87
  end
88
+
89
+ value.map do |k, v|
90
+ [
91
+ _convert(k, type.keys, raise_coercion_error),
92
+ _convert(v, type.values, raise_coercion_error),
93
+ ]
94
+ end.to_h
95
+ elsif Object.const_defined?('T::Private::Types::TypeAlias') &&
96
+ type.is_a?(T::Private::Types::TypeAlias)
97
+ _convert(value, type.aliased_type, raise_coercion_error)
98
+ elsif type.respond_to?(:<) && type < T::Struct
99
+ return value if value.is_a?(type)
100
+
101
+ args = _build_args(value, type, raise_coercion_error)
102
+ type.new(args)
103
+ else
104
+ return value if value.is_a?(type)
105
+
106
+ _convert_simple(value, type, raise_coercion_error)
116
107
  end
108
+ end
117
109
 
118
- sig { params(ary: T.untyped, type: T.untyped, raise_coercion_error: T::Boolean).returns(T.untyped) }
119
- def _convert_to_a(ary, type, raise_coercion_error)
120
- return [] if _nil_like?(ary, type)
110
+ def _convert_simple(value, type, raise_coercion_error)
111
+ return nil if _nil_like?(value, type)
121
112
 
122
- unless ary.respond_to?(:map)
123
- raise TypeCoerce::ShapeError.new(ary, type)
124
- end
113
+ safe_type_rule = T.let(nil, T.untyped)
125
114
 
126
- ary.map { |value| _convert(value, type, raise_coercion_error) }
115
+ if type == T::Boolean
116
+ safe_type_rule = SafeType::Boolean.strict
117
+ elsif value.is_a?(type)
118
+ return value
119
+ elsif PRIMITIVE_TYPES.include?(type)
120
+ safe_type_rule = SafeType.const_get(type.name).strict
121
+ else
122
+ safe_type_rule = type
127
123
  end
128
124
 
129
- sig { params(args: T.untyped, type: T.untyped, raise_coercion_error: T::Boolean).returns(T.untyped) }
130
- def _build_args(args, type, raise_coercion_error)
131
- return {} if _nil_like?(args, Hash)
125
+ if safe_type_rule.is_a?(SafeType::Rule)
126
+ SafeType::coerce(value, safe_type_rule)
127
+ else
128
+ type.new(value)
129
+ end
130
+ rescue SafeType::EmptyValueError, SafeType::CoercionError
131
+ if raise_coercion_error
132
+ raise TypeCoerce::CoercionError.new(value, type)
133
+ else
134
+ nil
135
+ end
136
+ end
132
137
 
133
- unless args.respond_to?(:each_pair)
134
- raise TypeCoerce::ShapeError.new(args, type)
135
- end
138
+ def _convert_to_a(ary, type, raise_coercion_error)
139
+ return [] if _nil_like?(ary, type)
136
140
 
137
- props = type.props
138
- args.map { |name, value|
139
- key = name.to_sym
140
- [
141
- key,
142
- (!props.include?(key) || value.nil?) ?
143
- nil : _convert(value, props[key][:type], raise_coercion_error),
144
- ]
145
- }.to_h.slice(*props.keys)
141
+ unless ary.respond_to?(:map)
142
+ raise TypeCoerce::ShapeError.new(ary, type)
146
143
  end
147
144
 
148
- sig { params(value: T.untyped, type: T.untyped).returns(T::Boolean) }
149
- def _nil_like?(value, type)
150
- value.nil? || (value == '' && type != String)
145
+ ary.map { |value| _convert(value, type, raise_coercion_error) }
146
+ end
147
+
148
+ def _build_args(args, type, raise_coercion_error)
149
+ return {} if _nil_like?(args, Hash)
150
+
151
+ unless args.respond_to?(:each_pair)
152
+ raise TypeCoerce::ShapeError.new(args, type)
151
153
  end
154
+
155
+ props = type.props
156
+ args.map { |name, value|
157
+ key = name.to_sym
158
+ [
159
+ key,
160
+ (!props.include?(key) || value.nil?) ?
161
+ nil : _convert(value, props[key][:type], raise_coercion_error),
162
+ ]
163
+ }.to_h.slice(*props.keys)
164
+ end
165
+
166
+ def _nil_like?(value, type)
167
+ value.nil? || (value == '' && type != String)
152
168
  end
153
169
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-coerce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chan Zuckerberg Initiative
@@ -122,7 +122,6 @@ files:
122
122
  - lib/sorbet-coerce.rb
123
123
  - lib/sorbet-coerce/configuration.rb
124
124
  - lib/sorbet-coerce/converter.rb
125
- - lib/sorbet-coerce/coverter.rbi
126
125
  - spec/coerce_spec.rb
127
126
  - spec/nested_spec.rb
128
127
  - spec/soft_error_spec.rb
@@ -148,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
147
  version: '0'
149
148
  requirements: []
150
149
  rubyforge_project:
151
- rubygems_version: 2.7.7
150
+ rubygems_version: 2.7.6.2
152
151
  signing_key:
153
152
  specification_version: 4
154
153
  summary: A type coercion lib works with Sorbet's static type checker and type definitions;
@@ -1,10 +0,0 @@
1
- # typed: true
2
- module T
3
- module Private
4
- module Types
5
- class TypeAlias
6
- def aliased_type; end
7
- end
8
- end
9
- end
10
- end