class Morpher::Transform::Hash

Transform a hash via mapping it over key specific transforms

Constants

KEY_MESSAGE
PRIMITIVE

Public Instance Methods

call(input) click to toggle source

Apply transformation to input

@param [Object] input

@return [Either<Error, Object>]

# File lib/morpher/transform.rb, line 363
def call(input)
  PRIMITIVE
    .call(input)
    .lmap(&method(:lift_error))
    .bind(&method(:reject_keys))
    .bind(&method(:transform))
end

Private Instance Methods

allowed_keys() click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/morpher/transform.rb, line 436
def allowed_keys
  required_keys + optional.map(&:value)
end
coerce_key(key, input) click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/morpher/transform.rb, line 411
def coerce_key(key, input)
  key.call(input.fetch(key.value)).lmap do |error|
    error(input: input, cause: error)
  end
end
defaults() click to toggle source
# File lib/morpher/transform.rb, line 383
def defaults
  optional.map(&:value).product([nil]).to_h
end
reject_keys(input) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/morpher/transform.rb, line 418
def reject_keys(input)
  keys       = input.keys
  unexpected = keys - allowed_keys
  missing    = required_keys - keys

  if unexpected.empty? && missing.empty?
    success(input)
  else
    failure(
      error(
        input:   input,
        message: KEY_MESSAGE % { missing: missing, unexpected: unexpected }
      )
    )
  end
end
required_keys() click to toggle source
# File lib/morpher/transform.rb, line 441
def required_keys
  required.map(&:value)
end
transform(input) click to toggle source
# File lib/morpher/transform.rb, line 373
def transform(input)
  transform_required(input).bind do |required|
    transform_optional(input).fmap(&required.public_method(:merge))
  end
end
transform_keys(keys, input) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/morpher/transform.rb, line 396
def transform_keys(keys, input)
  success(
    keys
      .to_h do |key|
        [
          key.value,
          coerce_key(key, input).from_right do |error|
            return failure(error)
          end
        ]
      end
  )
end
transform_optional(input) click to toggle source
# File lib/morpher/transform.rb, line 388
def transform_optional(input)
  transform_keys(
    optional.select { |key| input.key?(key.value) },
    input
  ).fmap(&defaults.public_method(:merge))
end
transform_required(input) click to toggle source
# File lib/morpher/transform.rb, line 379
def transform_required(input)
  transform_keys(required, input)
end