class SoberSwag::OutputObject
Create a serializer that is heavily inspired by the “Blueprinter” library. This allows you to make “views” and such inside.
Under the hood, this is actually all based on {SoberSwag::Serializer::Base}.
Attributes
@return [Array<SoberSwag::OutputObject::Field>]
@return [String] the external ID to use for this object
@return [Array<SoberSwag::OutputObject::View>]
Public Class Methods
Use a OutputObject
to define a new serializer. It will be based on {SoberSwag::Serializer::Base}.
An example is illustrative:
PersonSerializer = SoberSwag::OutputObject.define do field :id, primitive(:Integer) field :name, primitive(:String).optional view :complex do field :age, primitive(:Integer) field :title, primitive(:String) end end
Note: This currently will generate a new class that does serialization. However, this is only a hack to get rid of the weird naming issue when generating swagger from dry structs: their section of the schema area is defined by their *Ruby Class Name*. In the future, if we get rid of this, we might be able to keep this on the value-level, in which case {.define} can simply return an instance of SoberSwag::Serializer
that does the correct thing, with the name you give it. This works for now, though.
@return [Class] the serializer generated. @yieldself [SoberSwag::OutputObject::Definition]
# File lib/sober_swag/output_object.rb, line 41 def self.define(&block) d = Definition.new.tap do |o| o.instance_eval(&block) end new(d.fields, d.views, d.identifier) end
@param fields [Array<SoberSwag::OutputObject::Field>] the fields for this OutputObject
@param views [Array<SoberSwag::OutputObject::View>] the views for this OutputObject
@param identifier [String] the external identifier for this OutputObject
# File lib/sober_swag/output_object.rb, line 52 def initialize(fields, views, identifier) @fields = fields @views = views @identifier = identifier end
Public Instance Methods
A serializer for the “base type” of this OutputObject
, with no views.
# File lib/sober_swag/output_object.rb, line 93 def base base_serializer end
@return [SoberSwag::Serializer::FieldList] serializer for this output object.
# File lib/sober_swag/output_object.rb, line 120 def base_serializer @base_serializer ||= SoberSwag::Serializer::FieldList.new(fields).tap do |s| s.identifier(identifier) end end
Perform serialization.
# File lib/sober_swag/output_object.rb, line 70 def serialize(obj, opts = {}) serializer.serialize(obj, opts) end
Compile down this to an appropriate serializer. It uses {SoberSwag::Serializer::Conditional} to do view-parsing, and {SoberSwag::Serializer::FieldList} to do the actual serialization.
@todo: optimize view selection to use binary instead of linear search
# File lib/sober_swag/output_object.rb, line 103 def serializer @serializer ||= begin view_choices = views.map { |view| [view.name.to_s, view.serializer] }.to_h view_choices['base'] = base_serializer SoberSwag::Serializer::Hash.new(view_choices, base, proc { |_, options| options[:view]&.to_s }) end end
@return [String]
# File lib/sober_swag/output_object.rb, line 114 def to_s "<SoberSwag::OutputObject(#{identifier})>" end
Get a Dry::Struct of the type this OutputObject
will serialize to.
# File lib/sober_swag/output_object.rb, line 76 def type serializer.type end
Get a serializer for a single view contained in this output object. Note: given `:base`, it will return a serializer for the base OutputObject
@param name [Symbol] the name of the view @return [SoberSwag::Serializer::Base] the serializer
# File lib/sober_swag/output_object.rb, line 85 def view(name) return base_serializer if name == :base @views.find { |v| v.name == name } end