Class: RSchema::Schemas::FixedHash

Inherits:
Object
  • Object
show all
Defined in:
lib/rschema/schemas/fixed_hash.rb

Overview

A schema that matches Hash objects with known keys

Examples:

A typical fixed hash schema

schema = RSchema.define do
  fixed_hash(
    name: _String,
    optional(:age) => _Integer,
  )
end
schema.valid?({ name: "Tom" }) #=> true
schema.valid?({ name: "Dane", age: 55 }) #=> true

Defined Under Namespace

Classes: Attribute

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes) ⇒ FixedHash


20
21
22
# File 'lib/rschema/schemas/fixed_hash.rb', line 20

def initialize(attributes)
  @attributes = attributes
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes


18
19
20
# File 'lib/rschema/schemas/fixed_hash.rb', line 18

def attributes
  @attributes
end

Instance Method Details

#[](attr_key) ⇒ Object


45
46
47
# File 'lib/rschema/schemas/fixed_hash.rb', line 45

def [](attr_key)
  attributes.find{ |attr| attr.key == attr_key }
end

#call(value, options) ⇒ Object


24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rschema/schemas/fixed_hash.rb', line 24

def call(value, options)
  return not_a_hash_result(value) unless value.is_a?(Hash)
  return missing_attrs_result(value) if missing_keys(value).any?
  return extraneous_attrs_result(value) if extraneous_keys(value).any?

  subresults = attr_subresults(value, options)
  if subresults.values.any?(&:invalid?)
    Result.failure(failure_error(subresults))
  else
    Result.success(success_value(subresults))
  end
end

#merge(new_attributes) ⇒ FixedHash

Creates a new RSchema::Schemas::FixedHash schema with the given attributes merged in

Examples:

Merging new attributes into an existing RSchema::Schemas::FixedHash schema

person_schema = RSchema.define_hash {{
  name: _String,
  age: _Integer,
}}
person_schema.valid?(name: "t", age: 5) #=> true
person_schema.valid?(name: "t", age: 5, id: 3) #=> false

person_with_id_schema = RSchema.define do
  person_schema.merge(attributes(
    id: _Integer,
  ))
end
person_with_id_schema.valid?(name: "t", age: 5, id: 3) #=> true
person_with_id_schema.valid?(name: "t", age: 5) #=> false

71
72
73
74
75
76
77
78
# File 'lib/rschema/schemas/fixed_hash.rb', line 71

def merge(new_attributes)
  merged_attrs = (attributes + new_attributes)
    .map { |attr| [attr.key, attr] }
    .to_h
    .values

  self.class.new(merged_attrs)
end

#with_wrapped_subschemas(wrapper) ⇒ Object


37
38
39
40
41
42
43
# File 'lib/rschema/schemas/fixed_hash.rb', line 37

def with_wrapped_subschemas(wrapper)
  wrapped_attributes = attributes.map do |attr|
    attr.with_wrapped_value_schema(wrapper)
  end

  self.class.new(wrapped_attributes)
end

#without(attribute_keys) ⇒ FixedHash

Creates a new RSchema::Schemas::FixedHash schema with the given attributes removed

Examples:

Removing an attribute

cat_and_dog = RSchema.define_hash {{
  dog: _String,
  cat: _String,
}}

only_cat = RSchema.define { cat_and_dog.without(:dog) }
only_cat.valid?({ cat: 'meow' }) #=> true
only_cat.valid?({ cat: 'meow', dog: 'woof' }) #=> false

96
97
98
99
100
101
# File 'lib/rschema/schemas/fixed_hash.rb', line 96

def without(attribute_keys)
  filtered_attrs = attributes
    .reject { |attr| attribute_keys.include?(attr.key) }

  self.class.new(filtered_attrs)
end