class Functional::Record::Restrictions

@!visibility private

A set of restrictions governing the creation of a new record.

Public Class Methods

new(types = nil, &block) click to toggle source

Create a new restrictions object by processing the given block. The block should be the DSL for defining a record class.

@param [Hash] types a hash of fields and the associated type/protocol

when type/protocol checking is among the restrictions

@param [Proc] block A DSL definition of a new record. @yield A DSL definition of a new record.

# File lib/functional/record.rb, line 73
def initialize(types = nil, &block)
  @types = types
  @required = []
  @defaults = {}
  instance_eval(&block) if block_given?
  @required.freeze
  @defaults.freeze
  self.freeze
end

Public Instance Methods

clone_default(field) click to toggle source

Clone a default value if it is cloneable. Else just return the value.

@param [Symbol] field the name of the field from which the

default value is to be cloned.

@return [Object] a clone of the value or the value if uncloneable

# File lib/functional/record.rb, line 104
def clone_default(field)
  value = @defaults[field]
  value = value.clone unless uncloneable?(value)
rescue TypeError
  # can't be cloned
ensure
  return value
end
default(field, value) click to toggle source

DSL method for declaring a default value for a field

@param [Symbol] field the field to be given a default value @param [Object] value the default value of the field

# File lib/functional/record.rb, line 94
def default(field, value)
  @defaults[field] = value
end
mandatory(*fields) click to toggle source

DSL method for declaring one or more fields to be mandatory.

@param [Symbol] fields zero or more mandatory fields

# File lib/functional/record.rb, line 86
def mandatory(*fields)
  @required.concat(fields.collect{|field| field.to_sym})
end
validate!(data) click to toggle source

Validate the record data against this set of restrictions.

@param [Hash] data the data hash @raise [ArgumentError] when the data does not match the restrictions

# File lib/functional/record.rb, line 117
def validate!(data)
  validate_mandatory!(data)
  validate_types!(data)
end

Private Instance Methods

uncloneable?(object) click to toggle source

Is the given object uncloneable?

@param [Object] object the object to check @return [Boolean] true if the object cannot be cloned else false

# File lib/functional/record.rb, line 156
def uncloneable?(object)
  Type? object, NilClass, TrueClass, FalseClass, Fixnum, Bignum, Float
end
validate_mandatory!(data) click to toggle source

Check the given data hash to see if it contains non-nil values for all mandatory fields.

@param [Hash] data the data hash @raise [ArgumentError] if any mandatory fields are missing

# File lib/functional/record.rb, line 129
def validate_mandatory!(data)
  if data.any?{|k,v| @required.include?(k) && v.nil? }
    raise ArgumentError.new('mandatory fields must not be nil')
  end
end
validate_types!(data) click to toggle source

Validate the record data against a type/protocol specification.

@param [Hash] data the data hash @raise [ArgumentError] when the data does not match the specification

# File lib/functional/record.rb, line 139
def validate_types!(data)
  return if @types.nil?
  @types.each do |field, type|
    value = data[field]
    next if value.nil?
    if type.is_a? Module
      raise ArgumentError.new("'#{field}' must be of type #{type}") unless Type?(value, type)
    else
      raise ArgumentError.new("'#{field}' must stasify the protocol :#{type}") unless Satisfy?(value, type)
    end
  end
end