Sha256: 7bb2c1a2c47590536c25bdf304d3d9e09dec985db4a24898649966a8df642447

Contents?: true

Size: 1.33 KB

Versions: 1

Compression:

Stored size: 1.33 KB

Contents

# frozen_string_literal: true
module Speculation
  # @private
  class OrSpec < Spec
    include NamespacedSymbols
    S = Speculation

    attr_reader :id

    def initialize(named_specs)
      @id = SecureRandom.uuid
      @named_specs = named_specs
      @keys = named_specs.keys
      @preds = preds = named_specs.values

      @delayed_specs = Concurrent::Delay.new do
        preds.map { |spec| S.send(:specize, spec) }
      end
    end

    def conform(value)
      @delayed_specs.value!.each_with_index do |spec, index|
        conformed = spec.conform(value)

        unless S.invalid?(conformed)
          return [@keys[index], conformed]
        end
      end

      S::INVALID
    end

    def explain(path, via, inn, value)
      return if S.pvalid?(self, value)

      @keys.zip(@preds).flat_map do |(key, pred)|
        next if S.pvalid?(pred, value)
        S.explain1(pred, Utils.conj(path, key), via, inn, value)
      end
    end

    def gen(overrides, path, rmap)
      return gen if @gen

      gs = @keys.zip(@preds).
        map { |(k, p)|
          rmap = S.inck(rmap, @id)

          unless S.recur_limit?(rmap, @id, path, k)
            Gen.delay { S.gensub(p, overrides, Utils.conj(path, k), rmap) }
          end
        }.
        compact

      unless gs.empty?
        ->(rantly) { rantly.branch(*gs) }
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
speculation-0.3.0 lib/speculation/spec/or_spec.rb