Sha256: 64827ddd1383f13fd58aab1cdf2f2024db17b4a6a76ed172d7723cf81af5894b

Contents?: true

Size: 1.79 KB

Versions: 5

Compression:

Stored size: 1.79 KB

Contents

# frozen_string_literal: true

require 'plumb/composable'

module Plumb
  class HashMap
    include Composable

    attr_reader :children

    def initialize(key_type, value_type)
      @key_type = key_type
      @value_type = value_type
      @children = [key_type, value_type].freeze
      freeze
    end

    def call(result)
      return result.invalid(errors: 'must be a Hash') unless result.value.is_a?(::Hash)

      failed = result.value.lazy.filter_map do |key, value|
        key_r = @key_type.resolve(key)
        value_r = @value_type.resolve(value)
        if !key_r.valid?
          [:key, key, key_r]
        elsif !value_r.valid?
          [:value, value, value_r]
        end
      end
      if (first = failed.next)
        field, val, halt = failed.first
        result.invalid(errors: "#{field} #{val.inspect} #{halt.errors}")
      end
    rescue StopIteration
      result
    end

    def filtered
      FilteredHashMap.new(@key_type, @value_type)
    end

    private def _inspect = "HashMap[#{@key_type.inspect}, #{@value_type.inspect}]"

    class FilteredHashMap
      include Composable

      attr_reader :children

      def initialize(key_type, value_type)
        @key_type = key_type
        @value_type = value_type
        @children = [key_type, value_type].freeze
        freeze
      end

      def call(result)
        result.invalid(errors: 'must be a Hash') unless result.value.is_a?(::Hash)

        hash = result.value.each.with_object({}) do |(key, value), memo|
          key_r = @key_type.resolve(key)
          value_r = @value_type.resolve(value)
          memo[key_r.value] = value_r.value if key_r.valid? && value_r.valid?
        end

        result.valid(hash)
      end

      private def _inspect = "HashMap[#{@key_type.inspect}, #{@value_type.inspect}].filtered"
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
plumb-0.0.8 lib/plumb/hash_map.rb
plumb-0.0.7 lib/plumb/hash_map.rb
plumb-0.0.6 lib/plumb/hash_map.rb
plumb-0.0.5 lib/plumb/hash_map.rb
plumb-0.0.4 lib/plumb/hash_map.rb