Class: Philiprehberger::TypedHash::Instance

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/typed_hash/instance.rb

Overview

A typed hash instance with validation and coercion

Instance Method Summary collapse

Constructor Details

#initialize(schema, data) ⇒ Instance

Returns a new instance of Instance.

Parameters:

  • schema (Schema)

    the schema definition

  • data (Hash)

    the input data



9
10
11
12
13
14
15
16
# File 'lib/philiprehberger/typed_hash/instance.rb', line 9

def initialize(schema, data)
  @schema = schema
  @data = {}
  @errors = []
  @frozen = false

  process(data)
end

Instance Method Details

#[](key) ⇒ Object?

Access a value by key

Parameters:

  • key (Symbol)

    the key

Returns:

  • (Object, nil)

    the value



22
23
24
# File 'lib/philiprehberger/typed_hash/instance.rb', line 22

def [](key)
  @data[key]
end

#[]=(key, value) ⇒ Object

Set a value by key (raises if frozen)

Parameters:

  • key (Symbol)

    the key

  • value (Object)

    the value

Raises:



30
31
32
33
34
# File 'lib/philiprehberger/typed_hash/instance.rb', line 30

def []=(key, value)
  raise Philiprehberger::TypedHash::FrozenError, 'cannot modify a frozen instance' if @frozen

  @data[key] = value
end

#diff(other) ⇒ Hash

Compute the diff between this instance and another

Parameters:

  • other (Instance)

    the other instance to compare

Returns:

  • (Hash)

    diff of changed keys as { key => { old:, new: } }



112
113
114
115
116
117
118
119
# File 'lib/philiprehberger/typed_hash/instance.rb', line 112

def diff(other)
  all_keys = (to_h.keys | other.to_h.keys).uniq
  all_keys.each_with_object({}) do |key, result|
    old_val = self[key]
    new_val = other[key]
    result[key] = { old: old_val, new: new_val } unless old_val == new_val
  end
end

#errorsArray<String>

Return validation errors

Returns:

  • (Array<String>)

    the error messages



46
47
48
# File 'lib/philiprehberger/typed_hash/instance.rb', line 46

def errors
  @errors.dup
end

#freezeself

Freeze the instance, making it immutable

Returns:

  • (self)


96
97
98
99
# File 'lib/philiprehberger/typed_hash/instance.rb', line 96

def freeze
  @frozen = true
  self
end

#frozen?Boolean

Check if the instance is frozen

Returns:

  • (Boolean)


104
105
106
# File 'lib/philiprehberger/typed_hash/instance.rb', line 104

def frozen?
  @frozen
end

#merge(other) ⇒ Instance

Merge with another hash or Instance, returning a new Instance

Parameters:

  • other (Hash, Instance)

    the data to merge

Returns:

  • (Instance)

    a new typed hash instance



63
64
65
66
# File 'lib/philiprehberger/typed_hash/instance.rb', line 63

def merge(other)
  other_data = other.is_a?(Instance) ? other.to_h : other
  @schema.new(to_h.merge(other_data))
end

#omit(*keys) ⇒ Instance

Return a new Instance without the specified keys

Parameters:

  • keys (Array<Symbol>)

    keys to remove

Returns:

  • (Instance)

    a new typed hash instance



81
82
83
84
# File 'lib/philiprehberger/typed_hash/instance.rb', line 81

def omit(*keys)
  omitted = to_h.except(*keys)
  @schema.new(omitted)
end

#pick(*keys) ⇒ Instance

Return a new Instance with only the specified keys

Parameters:

  • keys (Array<Symbol>)

    keys to keep

Returns:

  • (Instance)

    a new typed hash instance



72
73
74
75
# File 'lib/philiprehberger/typed_hash/instance.rb', line 72

def pick(*keys)
  picked = to_h.slice(*keys)
  @schema.new(picked)
end

#to_hHash

Convert to a plain hash

Returns:

  • (Hash)

    the data as a hash



53
54
55
56
57
# File 'lib/philiprehberger/typed_hash/instance.rb', line 53

def to_h
  @data.each_with_object({}) do |(k, v), result|
    result[k] = v.is_a?(Instance) ? v.to_h : v
  end
end

#to_json(*_args) ⇒ String

Serialize to JSON string

Returns:

  • (String)

    JSON representation



89
90
91
# File 'lib/philiprehberger/typed_hash/instance.rb', line 89

def to_json(*_args)
  to_h.to_json
end

#valid?Boolean

Check if the instance is valid

Returns:

  • (Boolean)

    true if no validation errors



39
40
41
# File 'lib/philiprehberger/typed_hash/instance.rb', line 39

def valid?
  @errors.empty?
end