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

Returns a new instance of FixedHash.



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

def initialize(attributes)
  @attributes = attributes
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



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

def attributes
  @attributes
end

Instance Method Details

#[](attr_key) ⇒ Object



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

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

#call(value, options) ⇒ Object



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

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

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

Parameters:

  • new_attributes (Array<Attribute>)

    The attributes to merge

Returns:

  • (FixedHash)

    A new schema with the given attributes merged in



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

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



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

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

Parameters:

  • attribute_keys (Array<Object>)

    The keys to remove

Returns:

  • (FixedHash)

    A new schema with the given attributes removed



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

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

  self.class.new(filtered_attrs)
end