module T::Props::Private::SetterFactory

def self.build_setter_proc(klass, prop, rules)

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