Class: SoberSwag::OutputObject

Inherits:
Serializer::Base show all
Defined in:
lib/sober_swag/output_object.rb,
lib/sober_swag/output_object/view.rb,
lib/sober_swag/output_object/field.rb,
lib/sober_swag/output_object/definition.rb,
lib/sober_swag/output_object/field_syntax.rb

Overview

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 Serializer::Base.

Defined Under Namespace

Modules: FieldSyntax Classes: Definition, Field, View

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Serializer::Base

#array, #finalize_lazy_type!, #lazy_type, #lazy_type?, #meta, #optional, #via_map

Constructor Details

#initialize(fields, views, identifier) ⇒ OutputObject

Returns a new instance of OutputObject.

Parameters:



52
53
54
55
56
# File 'lib/sober_swag/output_object.rb', line 52

def initialize(fields, views, identifier)
  @fields = fields
  @views = views
  @identifier = identifier
end

Instance Attribute Details

#fieldsArray<SoberSwag::OutputObject::Field> (readonly)

Returns:



60
61
62
# File 'lib/sober_swag/output_object.rb', line 60

def fields
  @fields
end

#identifierString (readonly)

Returns the external ID to use for this object.

Returns:

  • (String)

    the external ID to use for this object



66
67
68
# File 'lib/sober_swag/output_object.rb', line 66

def identifier
  @identifier
end

#viewsArray<SoberSwag::OutputObject::View> (readonly)

Returns:



63
64
65
# File 'lib/sober_swag/output_object.rb', line 63

def views
  @views
end

Class Method Details

.define(&block) ⇒ Class

Use a OutputObject to define a new serializer. It will be based on 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.

Returns:

  • (Class)

    the serializer generated.



41
42
43
44
45
46
# 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

Instance Method Details

#baseObject

A serializer for the "base type" of this OutputObject, with no views.



93
94
95
# File 'lib/sober_swag/output_object.rb', line 93

def base
  base_serializer
end

#base_serializerSoberSwag::Serializer::FieldList

Returns serializer for this output object.

Returns:



120
121
122
123
124
# 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

#serialize(obj, opts = {}) ⇒ Object

Perform serialization.



70
71
72
# File 'lib/sober_swag/output_object.rb', line 70

def serialize(obj, opts = {})
  serializer.serialize(obj, opts)
end

#serializerObject

Compile down this to an appropriate serializer. It uses Serializer::Conditional to do view-parsing, and Serializer::FieldList to do the actual serialization.

@todo: optimize view selection to use binary instead of linear search



103
104
105
106
107
108
109
110
# 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

#to_sString

Returns:

  • (String)


114
115
116
# File 'lib/sober_swag/output_object.rb', line 114

def to_s
  "<SoberSwag::OutputObject(#{identifier})>"
end

#typeObject

Get a Dry::Struct of the type this OutputObject will serialize to.



76
77
78
# File 'lib/sober_swag/output_object.rb', line 76

def type
  serializer.type
end

#view(name) ⇒ SoberSwag::Serializer::Base

Get a serializer for a single view contained in this output object. Note: given :base, it will return a serializer for the base OutputObject

Parameters:

  • name (Symbol)

    the name of the view

Returns:



85
86
87
88
89
# 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