class TerminalShop::BaseModel

“‘
}
name: name
description: description,
id: id,
product_api => {
# `product_api` is a `TerminalShop::Models::ProductAPI`
“`ruby
@example
@abstract
@private

def ==(other)

Returns:
  • (Boolean) -

Parameters:
  • other (Object) --
def ==(other)
  case other
  in TerminalShop::BaseModel
    self.class.fields == other.class.fields && @data == other.to_h
  else
    false
  end
end

def [](key)

Returns:
  • (Object, nil) -

Parameters:
  • key (Symbol) --
def [](key)
  unless key.instance_of?(Symbol)
    raise ArgumentError.new("Expected symbol key for lookup, got #{key.inspect}")
  end
  @data[key]
end

def add_field(name_sym, required:, type_info:, spec:)

Options Hash: (**spec)
  • :"nil?" (Boolean) --
  • :union (Proc) --
  • :enum (Proc) --
  • :const (NilClass, TrueClass, FalseClass, Integer, Float, Symbol) --

Parameters:
  • spec (Hash{Symbol=>Object}) -- .
  • type_info (Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class) --
  • required (Boolean) --
  • name_sym (Symbol) --

Other tags:
    Private: -
def add_field(name_sym, required:, type_info:, spec:)
n, info =
 type_info
roc | Class | TerminalShop::Converter
erminalShop::Converter.type_info({**spec, union: type_info}), spec]
ash
erminalShop::Converter.type_info(type_info), type_info]
ck = info[:const]
ts[name_sym] = fallback if required && !info[:nil?] && info.key?(:const)
info.fetch(:api_name, name_sym)
 = "#{name_sym}="
wn_fields.key?(name_sym)
e_sym, setter].each { undef_method(_1) }
fields[name_sym] = {mode: @mode, key: key, required: required, type_fn: type_fn}
_method(setter) do |val|
a[key] = val
_method(name_sym) do
d_type = type_fn.call
e = @data.fetch(key) { self.class.defaults[key] }
inalShop::Converter.coerce(field_type, value)
 StandardError
 = self.class.name.split("::").last
e TerminalShop::ConversionError.new(
ailed to parse #{name}.#{name_sym} as #{field_type.inspect}. " \
o get the unparsed API response, use #{name}[:#{key}]."

def coerce(value)

Returns:
  • (TerminalShop::BaseModel, Object) -

Parameters:
  • value (TerminalShop::BaseModel, Hash{Object=>Object}, Object) --

Other tags:
    Private: -
def coerce(value)
  case TerminalShop::Util.coerce_hash(value)
  in Hash => coerced
    new(coerced)
  else
    value
  end
end

def deconstruct_keys(keys)

Returns:
  • (Hash{Symbol=>Object}) -

Parameters:
  • keys (Array, nil) --
def deconstruct_keys(keys)
  (keys || self.class.known_fields.keys).filter_map do |k|
    unless self.class.known_fields.key?(k)
      next
    end
    [k, method(k).call]
  end
  .to_h
end

def defaults = (@defaults ||= {})

Returns:
  • (Hash{Symbol=>Proc}) -

Other tags:
    Private: -
def defaults = (@defaults ||= {})

def dump(value)

Returns:
  • (Hash{Object=>Object}, Object) -

Parameters:
  • value (TerminalShop::BaseModel, Object) --

Other tags:
    Private: -
def dump(value)
  unless (coerced = TerminalShop::Util.coerce_hash(value)).is_a?(Hash)
    return value
  end
  values = coerced.filter_map do |key, val|
    name = key.to_sym
    case (field = known_fields[name])
    in nil
      [name, val]
    else
      mode, type_fn, api_name = field.fetch_values(:mode, :type_fn, :key)
      case mode
      in :coerce
        next
      else
        target = type_fn.call
        [api_name, TerminalShop::Converter.dump(target, val)]
      end
    end
  end.to_h
  defaults.each do |key, val|
    next if values.key?(key)
    values[key] = val
  end
  values
end

def fields

Returns:
  • (Hash{Symbol=>Hash{Symbol=>Object}}) -
def fields
  known_fields.transform_values do |field|
    {**field.except(:type_fn), type: field.fetch(:type_fn).call}
  end
end

def initialize(data = {})

Parameters:
  • data (Hash{Symbol=>Object}, TerminalShop::BaseModel) --
def initialize(data = {})
  case TerminalShop::Util.coerce_hash(data)
  in Hash => coerced
    @data = coerced.transform_keys(&:to_sym)
  else
    raise ArgumentError.new("Expected a #{Hash} or #{TerminalShop::BaseModel}, got #{data.inspect}")
  end
end

def inspect

Returns:
  • (String) -
def inspect
  "#<#{self.class.name}:0x#{object_id.to_s(16)} #{deconstruct_keys(nil).map do |k, v|
    "#{k}=#{v.inspect}"
  end.join(' ')}>"
end

def known_fields

Returns:
  • (Hash{Symbol=>Hash{Symbol=>Object}}) -

Other tags:
    Private: -
def known_fields
  @known_fields ||= (self < TerminalShop::BaseModel ? superclass.known_fields.dup : {})
end

def optional(name_sym, type_info, spec = {})

Options Hash: (**spec)
  • :"nil?" (Boolean) --
  • :union (Proc) --
  • :enum (Proc) --
  • :const (NilClass, TrueClass, FalseClass, Integer, Float, Symbol) --

Parameters:
  • spec (Hash{Symbol=>Object}) -- .
  • type_info (Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class) --
  • name_sym (Symbol) --

Other tags:
    Private: -
def optional(name_sym, type_info, spec = {})
  add_field(name_sym, required: false, type_info: type_info, spec: spec)
end

def request_only(&blk)

Parameters:
  • blk (Proc) --

Other tags:
    Private: -
def request_only(&blk)
= :dump
ll
= nil

def required(name_sym, type_info, spec = {})

Options Hash: (**spec)
  • :"nil?" (Boolean) --
  • :union (Proc) --
  • :enum (Proc) --
  • :const (NilClass, TrueClass, FalseClass, Integer, Float, Symbol) --

Parameters:
  • spec (Hash{Symbol=>Object}) -- .
  • type_info (Hash{Symbol=>Object}, Proc, TerminalShop::Converter, Class) --
  • name_sym (Symbol) --

Other tags:
    Private: -
def required(name_sym, type_info, spec = {})
  add_field(name_sym, required: true, type_info: type_info, spec: spec)
end

def response_only(&blk)

Parameters:
  • blk (Proc) --

Other tags:
    Private: -
def response_only(&blk)
= :coerce
ll
= nil

def to_h = @data

Returns:
  • (Hash{Symbol=>Object}) -
def to_h = @data

def to_s = @data.to_s

Returns:
  • (String) -
def to_s = @data.to_s

def try_strict_coerce(value)

Returns:
  • (Array(true, Object, nil), Array(false, Boolean, Integer)) -

Parameters:
  • value (Object) --

Other tags:
    Private: -
def try_strict_coerce(value)
  case value
  in Hash | TerminalShop::BaseModel
    value = value.to_h
  else
    return [false, false, 0]
  end
  keys = value.keys.to_set
  great_success = true
  tally = 0
  acc = {}
  known_fields.each_value do |field|
    mode, required, type_fn, api_name = field.fetch_values(:mode, :required, :type_fn, :key)
    keys.delete(api_name)
    case [required && mode != :dump, value.key?(api_name)]
    in [_, true]
      target = type_fn.call
      item = value.fetch(api_name)
      case TerminalShop::Converter.try_strict_coerce(target, item)
      in [true, coerced, score]
        tally += score
        acc[api_name] = coerced
      in [false, true, score]
        great_success = false
        tally += score
        acc[api_name] = item
      in [false, false, _]
        great_success &&= item.nil?
      end
    in [true, false]
      great_success = false
    in [false, false]
      nil
    end
  end
  keys.each do |key|
    acc[key] = value.fetch(key)
  end
  great_success ? [true, new(acc), tally] : [false, true, tally]
end