module T::Props::Private::SerdeTransform

def self.generate(type, mode, varname)

def self.generate(type, mode, varname)
  case type
  when T::Types::TypedArray
    inner = generate(type.type, mode, 'v')
    if inner.nil?
      "#{varname}.dup"
    else
      "#{varname}.map {|v| #{inner}}"
    end
  when T::Types::TypedSet
    inner = generate(type.type, mode, 'v')
    if inner.nil?
      "#{varname}.dup"
    else
      "Set.new(#{varname}) {|v| #{inner}}"
    end
  when T::Types::TypedHash
    keys = generate(type.keys, mode, 'k')
    values = generate(type.values, mode, 'v')
    if keys && values
      "#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}"
    elsif keys
      "#{varname}.transform_keys {|k| #{keys}}"
    elsif values
      "#{varname}.transform_values {|v| #{values}}"
    else
      "#{varname}.dup"
    end
  when T::Types::Simple
    raw = type.raw_type
    if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls}
      nil
    elsif raw < T::Props::Serializable
      handle_serializable_subtype(varname, raw, mode)
    elsif raw.singleton_class < T::Props::CustomType
      handle_custom_type(varname, T.unsafe(raw), mode)
    else
      "T::Props::Utils.deep_clone_object(#{varname})"
    end
  when T::Types::Union
    non_nil_type = T::Utils.unwrap_nilable(type)
    if non_nil_type
      inner = generate(non_nil_type, mode, varname)
      if inner.nil?
        nil
      else
        "#{varname}.nil? ? nil : #{inner}"
      end
    else
      "T::Props::Utils.deep_clone_object(#{varname})"
    end
  when T::Types::Enum
    generate(T::Utils.lift_enum(type), mode, varname)
  else
    if type.singleton_class < T::Props::CustomType
      # Sometimes this comes wrapped in a T::Types::Simple and sometimes not
      handle_custom_type(varname, T.unsafe(type), mode)
    else
      "T::Props::Utils.deep_clone_object(#{varname})"
    end
  end
end

def self.handle_custom_type(varname, type, mode)

def self.handle_custom_type(varname, type, mode)
E
t(module_name(type))
Type.checked_serialize(#{type_name}, #{varname})"
IZE
t(module_name(type))
erialize(#{varname})"

def self.handle_serializable_subtype(varname, type, mode)

def self.handle_serializable_subtype(varname, type, mode)
E
lize(strict)"
IZE
t(module_name(type))
m_hash(#{varname})"

def self.module_name(type)

def self.module_name(type)
pe).call