# frozen_string_literal: true # class UserSerializer < BasicSerializer # attribute :id, :integer # attribute :name, :string # attribute :email, :string # end require "oj" BasicStruct = Class.new(Struct) class BasicSerializer VERSION = "0.1.0" class << self def attributes @attributes ||= {} end def attribute(name, type) attributes[name] = type return if method_defined?(name) define_method(name) { object.send(name) } end def model_name(name) @model_name ||= name end def custom_model_name @model_name || name.gsub("Serializer", "") end def schema_ref(ref) @schema_ref ||= ref end end attr_reader :object def initialize(object) @object = object.is_a?(Hash) ? struct(object) : object end def as_json hash = {} self.class.attributes.each_key do |attr_name| hash[attr_name] = send(attr_name) end hash.transform_keys(&:to_s) end def to_json(*_args) Oj.dump(as_json) end def self.swagger_ref @schema_ref || "#/components/schemas/#{custom_model_name}" end def self.swagger_schema hash = { type: "object", properties: {} } attributes.each_pair do |name, type| hash[:properties][name] = { type: type } end hash end singleton_class.alias_method :openapi_ref, :swagger_ref singleton_class.alias_method :openapi_schema, :swagger_schema private def struct(object) return @struct if @struct basic_struct ||= BasicStruct.new(*object.keys.map(&:to_sym), keyword_init: true) @struct ||= basic_struct.new(**object) end end