Class: Yarrow::Schema::Dictionary

Inherits:
Object
  • Object
show all
Includes:
Definitions
Defined in:
lib/yarrow/schema/dictionary.rb

Overview

Specifies types plugged into each attribute slot and runs any required validations and coercions.

Current design throws on error rather than returns a boolean result.

Constant Summary

Constants included from Definitions

Yarrow::Schema::Definitions::DEFINED_TYPES, Yarrow::Schema::Definitions::TEMPLATE_TYPES

Instance Method Summary collapse

Methods included from Definitions

register, #resolve_type

Constructor Details

#initialize(attrs_spec = {}) ⇒ Dictionary

Returns a new instance of Dictionary.

Parameters:

  • attrs_spec (Hash) (defaults to: {})

    defines the slots in the schema to validate against



11
12
13
14
15
16
# File 'lib/yarrow/schema/dictionary.rb', line 11

def initialize(attrs_spec={})
  @attrs_spec = attrs_spec.reduce({}) do |spec, (name, type_identifier)|
    spec[name] = resolve_type(type_identifier)
    spec
  end
end

Instance Method Details

#attr_namesObject



22
23
24
# File 'lib/yarrow/schema/dictionary.rb', line 22

def attr_names
  @attrs_spec.keys
end

#cast(input, context = nil) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/yarrow/schema/dictionary.rb', line 26

def cast(input, context=nil)
  missing_attrs = @attrs_spec.keys.difference(input.keys)

  if missing_attrs.any?
    missing_attrs.each do |name|
      # TODO: add optional check
      raise "#{missing_attrs} wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
    end
  end

  mismatching_attrs = input.keys.difference(@attrs_spec.keys)

  raise "attribute #{mismatching_attrs} does not exist" if mismatching_attrs.any?

  input.reduce({}) do |converted, (name, value)|
    converted[name] = @attrs_spec[name].cast(value, context)
    converted
  end
end

#check(input) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/yarrow/schema/dictionary.rb', line 46

def check(input)
  missing_attrs = @attrs_spec.keys.difference(input.keys)

  if missing_attrs.any?
    missing_attrs.each do |name|
      raise "wrong number of attributes" unless @attrs_spec[name].eql?(Type::Any)
    end
  end

  mismatching_attrs = input.keys.difference(@attrs_spec.keys)

  raise "attribute does not exist" if mismatching_attrs.any?

  input.each do |(name, value)|
    unless value.is_a?(@attrs_spec[name]) || @attrs_spec[name].eql?(Type::Any)
      raise "wrong data type"
    end
  end

  true
end

#define_attribute(name, type_identifier) ⇒ Object



18
19
20
# File 'lib/yarrow/schema/dictionary.rb', line 18

def define_attribute(name, type_identifier)
  @attrs_spec[name] = resolve_type(type_identifier)
end