# frozen_string_literal: true# typed: strictmoduleT::PropsmodulePrivatemoduleSerdeTransformextendT::SigclassSerialize;endprivate_constant:SerializeclassDeserialize;endprivate_constant:DeserializeModeType=T.type_alias{T.any(Serialize,Deserialize)}private_constant:ModeTypemoduleModeSERIALIZE=T.let(Serialize.new.freeze,Serialize)DESERIALIZE=T.let(Deserialize.new.freeze,Deserialize)endNO_TRANSFORM_TYPES=T.let([TrueClass,FalseClass,NilClass,Symbol,String,Numeric].freeze,T::Array[Module],)private_constant:NO_TRANSFORM_TYPESsigdoparams(type: T.any(T::Types::Base,Module),mode: ModeType,varname: String,).returns(T.nilable(String)).checked(:never)enddefself.generate(type,mode,varname)casetypewhenT::Types::TypedArrayinner=generate(type.type,mode,'v')ifinner.nil?"#{varname}.dup"else"#{varname}.map {|v| #{inner}}"endwhenT::Types::TypedSetinner=generate(type.type,mode,'v')ifinner.nil?"#{varname}.dup"else"Set.new(#{varname}) {|v| #{inner}}"endwhenT::Types::TypedHashkeys=generate(type.keys,mode,'k')values=generate(type.values,mode,'v')ifkeys&&values"#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}"elsifkeys"#{varname}.transform_keys {|k| #{keys}}"elsifvalues"#{varname}.transform_values {|v| #{values}}"else"#{varname}.dup"endwhenT::Types::Simpleraw=type.raw_typeifNO_TRANSFORM_TYPES.any?{|cls|raw<=cls}nilelsifraw<T::Props::Serializablehandle_serializable_subtype(varname,raw,mode)elsifraw.singleton_class<T::Props::CustomTypehandle_custom_type(varname,T.unsafe(raw),mode)elsifT::Configuration.scalar_types.include?(raw.name)# It's a bit of a hack that this is separate from NO_TRANSFORM_TYPES# and doesn't check inheritance (like `T::Props::CustomType.scalar_type?`# does), but it covers the main use case (pay-server's custom `Boolean`# module) without either requiring `T::Configuration.scalar_types` to# accept modules instead of strings (which produces load-order issues# and subtle behavior changes) or eating the performance cost of doing# an inheritance check by manually crawling a class hierarchy and doing# string comparisons.nilelse"T::Props::Utils.deep_clone_object(#{varname})"endwhenT::Types::Unionnon_nil_type=T::Utils.unwrap_nilable(type)ifnon_nil_typeinner=generate(non_nil_type,mode,varname)ifinner.nil?nilelse"#{varname}.nil? ? nil : #{inner}"endelse# Handle, e.g., T::Booleaniftype.types.all?{|t|generate(t,mode,varname).nil?}nilelse"T::Props::Utils.deep_clone_object(#{varname})"endendwhenT::Types::Enumgenerate(T::Utils.lift_enum(type),mode,varname)elseiftype.singleton_class<T::Props::CustomType# Sometimes this comes wrapped in a T::Types::Simple and sometimes nothandle_custom_type(varname,T.unsafe(type),mode)else"T::Props::Utils.deep_clone_object(#{varname})"endendendsig{params(varname: String,type: Module,mode: ModeType).returns(String).checked(:never)}private_class_methoddefself.handle_serializable_subtype(varname,type,mode)casemodewhenSerialize"#{varname}.serialize(strict)"whenDeserializetype_name=T.must(module_name(type))"#{type_name}.from_hash(#{varname})"elseT.absurd(mode)endendsig{params(varname: String,type: Module,mode: ModeType).returns(String).checked(:never)}private_class_methoddefself.handle_custom_type(varname,type,mode)casemodewhenSerializetype_name=T.must(module_name(type))"T::Props::CustomType.checked_serialize(#{type_name}, #{varname})"whenDeserializetype_name=T.must(module_name(type))"#{type_name}.deserialize(#{varname})"elseT.absurd(mode)endend# Guard against overrides of `name` or `to_s`MODULE_NAME=T.let(Module.instance_method(:name),UnboundMethod)private_constant:MODULE_NAMEsig{params(type: Module).returns(T.nilable(String)).checked(:never)}private_class_methoddefself.module_name(type)MODULE_NAME.bind(type).callendendendend