module T::Props::Private::SetterFactory
Constants
- SetterProc
- ValidateProc
Public Class Methods
build_setter_proc(klass, prop, rules)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 21 def self.build_setter_proc(klass, prop, rules) # Our nil check works differently than a simple T.nilable for various # reasons (including the `raise_on_nil_write` setting and the existence # of defaults & factories), so unwrap any T.nilable and do a check # manually. non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)) accessor_key = rules.fetch(:accessor_key) validate = rules[:setter_validate] # It seems like a bug that this affects the behavior of setters, but # some existing code relies on this behavior has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil? # Use separate methods in order to ensure that we only close over necessary # variables if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default if validate.nil? && non_nil_type.is_a?(T::Types::Simple) simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass) else nilable_proc(prop, accessor_key, non_nil_type, klass, validate) end else if validate.nil? && non_nil_type.is_a?(T::Types::Simple) simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass) else non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) end end end
raise_pretty_error(klass, prop, type, val)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 175 def self.raise_pretty_error(klass, prop, type, val) base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}" pretty_message = "Parameter '#{prop}': #{base_message}\n" caller_loc = caller_locations&.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')} if caller_loc pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" end T::Configuration.call_validation_error_handler( nil, message: base_message, pretty_message: pretty_message, kind: 'Parameter', name: prop, type: type, value: val, location: caller_loc, ) end
Private Class Methods
nilable_proc(prop, accessor_key, non_nil_type, klass, validate)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 142 def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate) proc do |val| if val.nil? instance_variable_set(accessor_key, nil) # this use of recursively_valid? is intentional: unlike for # methods, we want to make sure data at the 'edge' # (e.g. models that go into databases or structs serialized # from disk) are correct, so we use more thorough runtime # checks there elsif non_nil_type.recursively_valid?(val) validate&.call(prop, val) instance_variable_set(accessor_key, val) else T::Props::Private::SetterFactory.raise_pretty_error( klass, prop, non_nil_type, val, ) instance_variable_set(accessor_key, val) end end end
non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 84 def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) proc do |val| # this use of recursively_valid? is intentional: unlike for # methods, we want to make sure data at the 'edge' # (e.g. models that go into databases or structs serialized # from disk) are correct, so we use more thorough runtime # checks there if non_nil_type.recursively_valid?(val) validate&.call(prop, val) else T::Props::Private::SetterFactory.raise_pretty_error( klass, prop, non_nil_type, val, ) end instance_variable_set(accessor_key, val) end end
simple_nilable_proc(prop, accessor_key, non_nil_type, klass)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 114 def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass) proc do |val| if val.nil? instance_variable_set(accessor_key, nil) elsif val.is_a?(non_nil_type) instance_variable_set(accessor_key, val) else T::Props::Private::SetterFactory.raise_pretty_error( klass, prop, T::Utils.coerce(non_nil_type), val, ) instance_variable_set(accessor_key, val) end end end
simple_non_nil_proc(prop, accessor_key, non_nil_type, klass)
click to toggle source
# File lib/types/props/private/setter_factory.rb, line 60 def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass) proc do |val| unless val.is_a?(non_nil_type) T::Props::Private::SetterFactory.raise_pretty_error( klass, prop, T::Utils.coerce(non_nil_type), val, ) end instance_variable_set(accessor_key, val) end end