Sha256: 00927da45fc80c446bd80fc59e865ca113349f653292c83fe1ab3319be1af11c

Contents?: true

Size: 1.32 KB

Versions: 6

Compression:

Stored size: 1.32 KB

Contents

module Option
  class Match

    def some(guard=always, &block)
      some_clauses << SomeClause.new(guard, block)
    end

    def none(&block)
      self.none_clause = NoneClause.new(block)
    end

    def evaluate(option)
      case option
      when Some
        matched(option).evaluate(option.value)
      when None
        none_clause.evaluate
      end
    end

    private

    def some_clauses
      @some_clauses ||= []
    end

    def none_clause
      @none_clause ||= NoneClause.new(lambda {})
    end

    def matched(option)
      some_clauses.find { |clause| clause.matches? option.value }.tap do |match|
        raise Option::BadMatchError if match.nil?
      end
    end

    def always
      lambda { |x| true }
    end

    attr_writer :none_clause

    class SomeClause

      def initialize(guard=always, block)
        @guard = guard
        @block = block
      end

      def matches?(value)
        guard.call(value)
      end

      def evaluate(value)
        block.call(value)
      end

      private

      attr_reader :block

      def guard
        @guard.is_a?(Proc) ? @guard : ->(x) { x == @guard }
      end

    end

    class NoneClause

      def initialize(block)
        @block = block
      end

      def evaluate
        block.call
      end

      private

      attr_reader :block
    end

  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
optional-0.0.6 lib/optional/option/match.rb
optional-0.0.5 lib/optional/option/match.rb
optional-0.0.4 lib/optional/option/match.rb
optional-0.0.3 lib/optional/option/match.rb
optional-0.0.2 lib/optional/option/match.rb
optional-0.0.1 lib/optional/option/match.rb