Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add coerce_empty_to_nil config for string conversion #65

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
pass in new option
  • Loading branch information
leifg committed Jul 17, 2022
commit da68f4ebb7064b369d8da51991ed08876a638059
44 changes: 22 additions & 22 deletions lib/sorbet-coerce/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ def to_s
"#{name}#[#{@type.to_s}]"
end

def from(args, raise_coercion_error: nil)
def from(args, raise_coercion_error: nil, coerce_empty_to_nil: false)
if raise_coercion_error.nil?
raise_coercion_error = TypeCoerce::Configuration.raise_coercion_error
end

T.let(_convert(args, @type, raise_coercion_error), @type)
T.let(_convert(args, @type, raise_coercion_error, coerce_empty_to_nil), @type)
end

private
Expand All @@ -45,19 +45,19 @@ def from(args, raise_coercion_error: nil)
Time,
], T.untyped)

def _convert(value, type, raise_coercion_error)
def _convert(value, type, raise_coercion_error, coerce_empty_to_nil)
if type.is_a?(T::Types::Untyped)
value
elsif type.is_a?(T::Types::ClassOf)
value
elsif type.is_a?(T::Types::TypedArray)
_convert_to_a(value, type.type, raise_coercion_error)
_convert_to_a(value, type.type, raise_coercion_error, coerce_empty_to_nil)
elsif type.is_a?(T::Types::FixedArray)
_convert_to_a(value, type.types, raise_coercion_error)
_convert_to_a(value, type.types, raise_coercion_error, coerce_empty_to_nil)
elsif type.is_a?(T::Types::TypedSet)
Set.new(_convert_to_a(value, type.type, raise_coercion_error))
Set.new(_convert_to_a(value, type.type, raise_coercion_error, coerce_empty_to_nil))
elsif type.is_a?(T::Types::Simple)
_convert(value, type.raw_type, raise_coercion_error)
_convert(value, type.raw_type, raise_coercion_error, coerce_empty_to_nil)
elsif type.is_a?(T::Types::Union)
true_idx = T.let(nil, T.nilable(Integer))
false_idx = T.let(nil, T.nilable(Integer))
Expand All @@ -77,9 +77,9 @@ def _convert(value, type, raise_coercion_error)
)

if !true_idx.nil? && !false_idx.nil?
_convert_simple(value, T::Boolean, raise_coercion_error)
_convert_simple(value, T::Boolean, raise_coercion_error, coerce_empty_to_nil)
else
_convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error)
_convert(value, type.types[nil_idx == 0 ? 1 : 0], raise_coercion_error, coerce_empty_to_nil)
end
elsif type.is_a?(T::Types::TypedHash)
return {} if _nil_like?(value, type)
Expand All @@ -90,23 +90,23 @@ def _convert(value, type, raise_coercion_error)

value.map do |k, v|
[
_convert(k, type.keys, raise_coercion_error),
_convert(v, type.values, raise_coercion_error),
_convert(k, type.keys, raise_coercion_error, coerce_empty_to_nil),
_convert(v, type.values, raise_coercion_error, coerce_empty_to_nil),
]
end.to_h
elsif Object.const_defined?('T::Private::Types::TypeAlias') &&
type.is_a?(T::Private::Types::TypeAlias)
_convert(value, type.aliased_type, raise_coercion_error)
_convert(value, type.aliased_type, raise_coercion_error, coerce_empty_to_nil)
elsif type.is_a?(Class) || type.is_a?(Module)
return value if value.is_a?(type)

if type < T::Struct
args = _build_args(value, type, raise_coercion_error)
args = _build_args(value, type, raise_coercion_error, coerce_empty_to_nil)
type.new(args)
elsif type < T::Enum
_convert_enum(value, type, raise_coercion_error)
_convert_enum(value, type, raise_coercion_error, coerce_empty_to_nil)
else
_convert_simple(value, type, raise_coercion_error)
_convert_simple(value, type, raise_coercion_error, coerce_empty_to_nil)
end
else
if raise_coercion_error
Expand All @@ -117,7 +117,7 @@ def _convert(value, type, raise_coercion_error)
end
end

def _convert_enum(value, type, raise_coercion_error)
def _convert_enum(value, type, raise_coercion_error, coerce_empty_to_nil)
if raise_coercion_error
type.deserialize(value)
else
Expand All @@ -127,7 +127,7 @@ def _convert_enum(value, type, raise_coercion_error)
raise TypeCoerce::CoercionError.new(value, type)
end

def _convert_simple(value, type, raise_coercion_error)
def _convert_simple(value, type, raise_coercion_error, coerce_empty_to_nils)
return nil if _nil_like?(value, type)

safe_type_rule = T.let(nil, T.untyped)
Expand Down Expand Up @@ -157,7 +157,7 @@ def _convert_simple(value, type, raise_coercion_error)
end
end

def _convert_to_a(ary, type, raise_coercion_error)
def _convert_to_a(ary, type, raise_coercion_error, coerce_empty_to_nil)
return [] if _nil_like?(ary, type)

unless ary.respond_to?(:map)
Expand All @@ -166,14 +166,14 @@ def _convert_to_a(ary, type, raise_coercion_error)

ary.map.with_index do |value, i|
if type.is_a?(Array)
_convert(value, type[i], raise_coercion_error)
_convert(value, type[i], raise_coercion_error, coerce_empty_to_nil)
else
_convert(value, type, raise_coercion_error)
_convert(value, type, raise_coercion_error, coerce_empty_to_nil)
end
end
end

def _build_args(args, type, raise_coercion_error)
def _build_args(args, type, raise_coercion_error, coerce_empty_to_nil)
return {} if _nil_like?(args, Hash)

unless args.respond_to?(:each_pair)
Expand All @@ -186,7 +186,7 @@ def _build_args(args, type, raise_coercion_error)
[
key,
(!props.include?(key) || value.nil?) ?
nil : _convert(value, props[key][:type], raise_coercion_error),
nil : _convert(value, props[key][:type], raise_coercion_error, coerce_empty_to_nil),
]
}.to_h.slice(*props.keys)
end
Expand Down