Class: SoberSwag::InputObject

Inherits:
Dry::Struct
  • Object
show all
Includes:
Type::Named
Defined in:
lib/sober_swag/input_object.rb

Overview

A variant of Dry::Struct that allows you to set a "model name" that is publicly visible. If you do not set one, it will be the Ruby class name, with any '::' replaced with a '.'.

This otherwise behaves exactly like a Dry::Struct. Please see the documentation for that class to see how it works.

Class Method Summary collapse

Methods included from Type::Named

included

Class Method Details

.attribute(key, parent = SoberSwag::InputObject, &block) ⇒ Object .attribute(key, type) ⇒ Object

Overloads:

  • .attribute(key, parent = SoberSwag::InputObject, &block) ⇒ Object

    Defines an attribute as a direct sub-object. This block will be called as in SoberSwag.input_object. This might be useful in a case like the following:

    class Classroom < SoberSwag::InputObject
      attribute :biographical_detail do
        attribute :student_name, primitive(:String)
      end
    end
    

    Parameters:

    • key (Symbol)

      the attribute name

    • parent (Class) (defaults to: SoberSwag::InputObject)

      the parent class to use for the sub-object

  • .attribute(key, type) ⇒ Object

    Defines a new attribute with the given type.

    Parameters:

    • key (Symbol)

      the attribute name

    • type

      the attribute type

Raises:

  • (ArgumentError)


43
44
45
46
47
48
# File 'lib/sober_swag/input_object.rb', line 43

def attribute(key, parent = SoberSwag::InputObject, &block)
  raise ArgumentError, "parent class #{parent} is not an input object type!" unless valid_field_def?(parent, block)
  raise ArgumentError, "cannot mix reporting and non-reporting types at attribute #{key}" if parent.is_a?(SoberSwag::Reporting::Input::Interface)

  super(key, parent, &block)
end

.attribute(key, parent = SoberSwag::InputObject, &block) ⇒ Boolean .attribute(key, type) ⇒ Boolean

Overloads:

  • .attribute(key, parent = SoberSwag::InputObject, &block) ⇒ Boolean

    Defines an optional attribute by defining a sub-object inline. This differs from a nil-able attribute as it can be not provided, while nilable attributes must be set to null.

    Yields to the block like in SoberSwag.input_object

    Parameters:

    • key (Symbol)

      the attribute name

    • parent (Class) (defaults to: SoberSwag::InputObject)

      the parent class to use for the sub-object

  • .attribute(key, type) ⇒ Boolean

    Defines an optional attribute with a given type. This differs from a nil-able attribute as it can be not provided, while nilable attributes must be set to null.

    Parameters:

    • key (Symbol)

      the attribute name

    • type

      the attribute type, another parsable object.

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


99
100
101
102
103
# File 'lib/sober_swag/input_object.rb', line 99

def attribute?(key, parent = SoberSwag::InputObject, &block)
  raise ArgumentError, "parent class #{parent} is not an input object type!" unless valid_field_def?(parent, block)

  super(key, parent, &block)
end

.identifier(new_ident = nil) ⇒ Object

The name to use for this type in external documentation.

Parameters:

  • new_ident (String) (defaults to: nil)

    what to call this InputObject in external documentation.



17
18
19
20
21
# File 'lib/sober_swag/input_object.rb', line 17

def identifier(new_ident = nil)
  @identifier = new_ident if new_ident

  @identifier || name.to_s.gsub('::', '.')
end

.meta(*args) ⇒ SoberSwag::InputObject

Add metadata keys, like :description, to the defined type. Note: does NOT mutate the type, returns a new type with the metadata added.

Parameters:

  • args (Hash)

    the argument values

Returns:



111
112
113
114
115
116
117
118
119
120
# File 'lib/sober_swag/input_object.rb', line 111

def meta(*args)
  original = self

  super(*args).tap do |result|
    return result unless result.is_a?(Class)

    result.define_singleton_method(:alias?) { true }
    result.define_singleton_method(:alias_of) { original }
  end
end

.param(name) ⇒ Object

Convenience method: you can use .param to get a parameter parser of a given type. Said parsers are more loose: for example, param(:Integer) will parse the string "10" into 10, while primitive(:Integer) will throw an error.

This method lets you write:

class Foo < SoberSwag::InputObject
  attribute :bar, param(:Integer)
end

instead of

class Foo < SoberSwag::InputObject
  attribute :bar, SoberSwag::Types::Param::Integer
end

Parameters:

  • name (Symbol)

    the name of the parameter type to get

Returns:

  • a parameter parser



173
174
175
# File 'lib/sober_swag/input_object.rb', line 173

def param(name)
  SoberSwag::Types::Params.const_get(name)
end

.primitive(*args) ⇒ Object

Convenience method: you can use .primitive get a primitive parser for a given type. This lets you write:

 class Foo < SoberSwag::InputObject
   attribute :bar, primitive(:String)
 end

instead of

class Foo < SoberSwag::InputObject
  attribute :bar, SoberSwag::Types::String
end

Parameters:

  • args (Symbol)

    a symbol

Returns:

  • a primitive parser



142
143
144
145
146
147
148
# File 'lib/sober_swag/input_object.rb', line 142

def primitive(*args)
  if args.length == 1
    SoberSwag::Types.const_get(args.first)
  else
    super
  end
end

.type_attribute(value, attribute_key: :type) ⇒ Object

Add on an attribute which only ever parses from a constant value. By default, this attribute will be called type, but you can override it with the kwarg. This is useful in situations where you want to emulate a sum type. For example, if you want to make an API endpoint that can either accept or reject proposals


ApiInputType = SoberSwag.input_object {
  identifier 'AcceptProposal'
  type_attribute 'accept'
  attribute(:message, primitive(:String))
} | SoberSwag.input_object {
  identifier 'RejectProposal'
  type_attribute 'reject'
  attribute(:message, primitive(:String))
}

Under the hood, this basically looks like:

type_attribute 'archive'
# is equivalent to

attribute(:type, SoberSwag::Types::String.enum('archive'))

Parameters:

  • value (String, Symbol)

    the value to parse

  • attribute_key (Symbol) (defaults to: :type)

    what key to use



80
81
82
# File 'lib/sober_swag/input_object.rb', line 80

def type_attribute(value, attribute_key: :type)
  attribute(attribute_key, SoberSwag::Types::String.enum(value.to_s))
end

.valid_field_def?(parent, block) ⇒ Boolean (private)

Returns:

  • (Boolean)


179
180
181
182
183
# File 'lib/sober_swag/input_object.rb', line 179

def valid_field_def?(parent, block)
  return true if block.nil?

  parent.is_a?(Class) && parent <= SoberSwag::InputObject
end