class SoberSwag::Reporting::Input::Struct

Base class of input structs.

These allow you to define both an input type and a ruby type at once. They provide a fluid interface for doing so.

Classes which inherit from {Struct} “quack like” an {Interface}, so you can use them as input type definitions.

You should add attributes using the {.attribute} or {.attribute?} methods. These also let you nest definitions, so this is okay:

“`ruby class Person < SoberSwag::Reporting::Input::Struct

attribute :first_name, SoberSwag::Reporting::Input.text
attribute :stats do
  attribute :average_score, SoberSwag::Reporting::Input.number
end

end “`

Attributes

parent_struct[RW]

@return [SoberSwag::Reporting::Input::Struct,nil] the struct we inherit from.

Used to implement `allOf` style inheritance.
struct_properties[R]

Public Class Methods

add_attribute!(name, input, required:, description: nil) click to toggle source

Add an attribute, specifying if it is required or not via an argument. You should use {#attribute} or {#attribute?} instead of this almost always.

@param name [Symbol] name of this attribute @param input [Interface] type fot this attribue @param required [true,false] if this attribute is required @param description [String,nil] optional description for this attribute

# File lib/sober_swag/reporting/input/struct.rb, line 77
def add_attribute!(name, input, required:, description: nil)
  raise ArgumentError, 'name must be a symbol' unless name.is_a?(Symbol)

  define_attribute(name) # defines an instance method to access this attribute

  object_properties[name] = Object::Property.new(
    input,
    required: required,
    description: description
  )
end
attribute(name, input = nil, description: nil, &block) click to toggle source

@overload attribute(name, input, description: nil)

Define a new attribute, which will be required.
@param name [Symbol] the name of this attribute
@param input [Interface] input reporting type
@param description [String,nil] description for this attribute

@overload attribute(name, description: nil, &block)

Define a new nested attribute, which will be required, using a block to describe
a sub-struct. This block will immediately be evaluated to create a child struct.
@param name [Symbol] the name of the attribute.
  The sub-struct defined will be stored in a constant on this class,
  under this name, classified.

  So if the name is :first_name, then the constant will be FirstName
@param description [String, nil] describe this attribute
@yieldself [SoberSwag::Reporting::Input::Struct] yields
# File lib/sober_swag/reporting/input/struct.rb, line 41
def attribute(name, input = nil, description: nil, &block)
  input_type = make_input_type(name, input, block)
  add_attribute!(name, input_type, required: true, description: description)
end
attribute?(name, input = nil, description: nil, &block) click to toggle source

@overload attribute?(name, input, description: nil)

Define a new attribute, which will be not required.
@param name [Symbol] the name of this attribute
@param input [Interface] input reporting type
@param description [String,nil] description for this attribute

@overload attribute?(name, description: nil, &block)

Define a new nested attribute, which will not be required, using a block to describe
a sub-struct. This block will immediately be evaluated to create a child struct.
@param name [Symbol] the name of the attribute.
  The sub-struct defined will be stored in a constant on this class,
  under this name, classified.

  So if the name is :first_name, then the constant will be FirstName
@param description [String, nil] describe this attribute
@yieldself [SoberSwag::Reporting::Input::Struct] yields
# File lib/sober_swag/reporting/input/struct.rb, line 62
def attribute?(name, input = nil, description: nil, &block)
  input_type = make_input_type(name, input, block)

  add_attribute!(name, input_type, required: false, description: description)
end
call(attrs) click to toggle source

@return [SoberSwag::Reporting::Input::Struct, SoberSwag::Reporting::Report::Base] the struct class,

or a report of what went wrong.
# File lib/sober_swag/reporting/input/struct.rb, line 138
def call(attrs)
  input_type.call(attrs)
end
identifier(val = nil) click to toggle source

@overload identifier()

@return [String,nil] the identifier for this object, used for its reference path.

@overload identifier(val)

Sets an identifier for this struct.
@param val [String] the identifier to set
@return [String] the set identifier.
# File lib/sober_swag/reporting/input/struct.rb, line 127
def identifier(val = nil)
  if val
    @identifier = val
  else
    @identifier || name&.gsub('::', '.')
  end
end
inherited(other) click to toggle source

@param other [Class] the inheriting class

Used to implement `allOf` style inheritance by setting {#parent_struct} on the object that is inheriting from us.

# File lib/sober_swag/reporting/input/struct.rb, line 108
def inherited(other)
  other.parent_struct = self unless self == SoberSwag::Reporting::Input::Struct
end
input_type() click to toggle source

@return [SoberSwag::Reporting::Input::Base] the type to use for input.

# File lib/sober_swag/reporting/input/struct.rb, line 116
def input_type
  object_type.mapped { |x| new(x) }.referenced(identifier)
end
new(props) click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 204
def initialize(props)
  @struct_properties = props
end
object_properties() click to toggle source

Get a list of properties defined by *this instance*.

Please do not mutate this, it will break everything.

@return [Hash<Symbol, Object::Property>]

# File lib/sober_swag/reporting/input/struct.rb, line 95
def object_properties
  @object_properties ||= {}
end
parse(json) click to toggle source

@see call

# File lib/sober_swag/reporting/input/struct.rb, line 144
def parse(json)
  call(json)
end
parse!(json) click to toggle source

@see call!

# File lib/sober_swag/reporting/input/struct.rb, line 150
def parse!(json)
  call!(json)
end
swagger_path_schema() click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 164
def swagger_path_schema
  object_type.swagger_path_schema
end
swagger_query_schema() click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 160
def swagger_query_schema
  object_type.swagger_query_schema
end
swagger_schema() click to toggle source

@return [Array[Hash, Hash]] swagger schema type.

# File lib/sober_swag/reporting/input/struct.rb, line 156
def swagger_schema
  input_type.swagger_schema
end

Private Class Methods

define_attribute(name) click to toggle source

Quick method which defines an accessor method for this struct.

# File lib/sober_swag/reporting/input/struct.rb, line 186
def define_attribute(name)
  define_method(name) do
    struct_properties[name]
  end
  define_method("#{name}_present?") do
    struct_properties.key?(name)
  end
end
make_input_type(name, input, block) click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 170
def make_input_type(name, input, block)
  raise ArgumentError, 'cannot pass a block to make a sub-struct and a field type' if input && block

  return input if input

  raise ArgumentError, 'must pass an input type OR a block to make a sub-struct' unless block

  const_name = name.to_s.camelize

  raise ArgumentError, 'cannot define struct sub-type, constant already exists!' if const_defined?(const_name)

  Class.new(SoberSwag::Reporting::Input::Struct, &block).tap { |c| const_set(const_name, c) }
end
object_type() click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 195
def object_type
  if parent_struct.nil?
    Object.new(object_properties)
  else
    MergeObjects.new(parent_struct, Object.new(object_properties))
  end
end

Public Instance Methods

<=>(other) click to toggle source

Allow structs to be ordered like values.

# File lib/sober_swag/reporting/input/struct.rb, line 236
def <=>(other)
  return nil unless other.is_a?(self.class)

  ordered_values <=> other.ordered_values
end
[](name) click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 210
def [](name)
  @struct_properties[name]
end
eql?(other) click to toggle source

Allow structs to be compared like values.

# File lib/sober_swag/reporting/input/struct.rb, line 228
def eql?(other)
  return false unless other.is_a?(self.class)

  ordered_values.eql?(other.ordered_values)
end
hash() click to toggle source

Hash code for this struct.

# File lib/sober_swag/reporting/input/struct.rb, line 216
def hash
  [self.class.hash, *ordered_values.hash].hash
end
inspect() click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 262
def inspect
  keys = self.class.object_properties.keys.each.with_object([]) do |k, obj|
    obj << "#{k}=#{public_send(k).inspect}" if public_send(:"#{k}_present?")
  end
  "#<#{self.class.name || self.class.inspect[2..-2]} #{keys.join(' ')}>"
end
ordered_values() click to toggle source

Return an array of the values of this, in order.

# File lib/sober_swag/reporting/input/struct.rb, line 222
def ordered_values
  self.class.object_properties.keys.map { |k| @struct_properties[k] }
end
to_h() click to toggle source

Extracts the transformed struct properties.

Keys not present in the input will also not be present in this hash.

# File lib/sober_swag/reporting/input/struct.rb, line 248
def to_h
  @struct_properties.transform_values do |value|
    if value.is_a?(SoberSwag::Reporting::Input::Struct)
      value.to_h
    else
      value
    end
  end
end
to_s() click to toggle source
# File lib/sober_swag/reporting/input/struct.rb, line 258
def to_s
  inspect
end