class Sorta::Lens::Typed

Extracts data from a given object

Public Class Methods

new(**kwargs) click to toggle source
# File lib/lens/typed_lens.rb, line 11
def initialize(**kwargs)
  @kwargs = kwargs
  validate_arguments
end
on(...) click to toggle source
# File lib/lens/typed_lens.rb, line 7
def self.on(...)
  new(...)
end

Public Instance Methods

call(object) click to toggle source
# File lib/lens/typed_lens.rb, line 16
def call(object)
  @getable = object.respond_to? :[]
  result = @kwargs.each_with_object({}) do |(sym, _ty), acc|
    val = extract(sym, object)
    acc[sym] = typecheck(sym, val)
  end
  @getable = nil
  result
end
extract(sym, object) click to toggle source
# File lib/lens/typed_lens.rb, line 35
def extract(sym, object)
  if @getable
    object[sym]
  elsif object.respond_to? sym
    object.send(sym)
  end
end
typecheck(sym, val) click to toggle source
# File lib/lens/typed_lens.rb, line 43
def typecheck(sym, val)
  ty = @kwargs[sym]
  return val if val.is_a?(ty)

  raise TypeError.new val.class, ty
end
validate_arguments() click to toggle source
# File lib/lens/typed_lens.rb, line 26
def validate_arguments
  @kwargs.each do |(sym, ty)|
    unless sym.is_a?(Symbol) && ty.is_a?(Class)
      raise ArgumentError,
            "Unexpected argument (#{sym.class} => #{ty.class}), must be (Symbol => Class)"
    end
  end
end