module T::Props::Private::SerializerGenerator

def self.generate(props)

def self.generate(props)
  stored_props = props.reject {|_, rules| rules[:dont_store]}
  parts = stored_props.map do |prop, rules|
    # All of these strings should already be validated (directly or
    # indirectly) in `validate_prop_name`, so we don't bother with a nice
    # error message, but we double check here to prevent a refactoring
    # from introducing a security vulnerability.
    raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s)
    hash_key = rules.fetch(:serialized_form)
    raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key)
    ivar_name = rules.fetch(:accessor_key).to_s
    raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1])
    transformed_val = SerdeTransform.generate(
      T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)),
      SerdeTransform::Mode::SERIALIZE,
      ivar_name
    ) || ivar_name
    nil_asserter =
      if rules[:fully_optional]
        ''
      else
        "required_prop_missing_from_serialize(#{prop.inspect}) if strict"
      end
    # Don't serialize values that are nil to save space (both the
    # nil value itself and the field name in the serialized BSON
    # document)
    <<~RUBY
      if #{ivar_name}.nil?
        #{nil_asserter}
      else
        h[#{hash_key.inspect}] = #{transformed_val}
      end
    RUBY
  end
  <<~RUBY
    def __t_props_generated_serialize(strict)
      h = {}
      #{parts.join("\n\n")}
      h
    end
  RUBY
end