class Manioc::Struct

Public Class Methods

configure(fields: [], defaults: {}) click to toggle source
# File lib/manioc/struct.rb, line 32
def self.configure fields: [], defaults: {}, mutable: Manioc.frozen?
  config = Config.new.tap do |c|
    c.fields   = fields + defaults.keys
    c.defaults = defaults
    c.mutable  = mutable
  end

  Class.new Struct do
    define_singleton_method(:config) { config }

    config.fields.each do |field|
      if config.mutable
        attr_accessor field
      else
        attr_reader field
      end
    end
  end
end
new(**fields) click to toggle source
# File lib/manioc/struct.rb, line 52
def initialize **fields
  fields = self.class.config.defaults.merge fields
  _validate fields
  _assign   fields
  freeze if Manioc.frozen? && self.class.config.immutable?
end

Public Instance Methods

==(other) click to toggle source
Calls superclass method
# File lib/manioc/struct.rb, line 59
def == other
  super || to_h == other.to_h
end
inspect() click to toggle source
# File lib/manioc/struct.rb, line 71
def inspect
  # :nocov:
  %|<#{self.class.name}(#{self.class.config.fields.join(', ')})>|
  # :nocov:
end
to_h() click to toggle source
# File lib/manioc/struct.rb, line 67
def to_h
  self.class.config.fields.each_with_object({}) { |field,h| h[field] = public_send field }
end
with(**fields) click to toggle source
# File lib/manioc/struct.rb, line 63
def with **fields
  self.class.new to_h.merge fields
end

Private Instance Methods

_assign(fields) click to toggle source
# File lib/manioc/struct.rb, line 91
def _assign fields
  fields.each { |k,v| instance_variable_set :"@#{k}", v }
end
_validate(fields) click to toggle source
# File lib/manioc/struct.rb, line 79
def _validate fields
  missing = self.class.config.fields - fields.keys
  if missing.any?
    raise KeyError, "#{self}(#{self.class}) missing fields #{missing}"
  end

  extra = fields.keys - self.class.config.fields
  if extra.any?
    raise KeyError, "#{self}(#{self.class}) passed extra fields #{extra}"
  end
end