Sha256: 4c9d17eb07dec91c079b561d968a39beeece995375db6595cfb5dac13d032dc0

Contents?: true

Size: 1.65 KB

Versions: 2

Compression:

Stored size: 1.65 KB

Contents

module Unitwise
  module Expression
    # The decomposer is used to turn string expressions into collections of
    # terms. It is responsible for executing the parsing and transformation
    # of a string, as well as caching the results.
    class Decomposer

      MODES = [:primary_code, :secondary_code, :names, :slugs, :symbol]

      PARSERS = MODES.reduce({}) do |hash, mode|
        hash[mode] = Parser.new(mode); hash
      end

      TRANSFORMER = Transformer.new

      class << self

        # Parse an expression to an array of terms and cache the results
        def parse(expression)
          expression = expression.to_s
          if cache.key?(expression)
            cache[expression]
          elsif decomposer = new(expression)
            cache[expression] = decomposer
          end
        end

        private

        # A simple cache to prevent re-decomposing the same units
        # api private
        def cache
          @cache ||= {}
        end
      end

      attr_reader :expression, :mode

      def initialize(expression)
        @expression = expression.to_s
        if terms.nil? || terms.empty?
          fail(ExpressionError, "Could not evaluate '#{ expression }'.")
        end
      end

      def parse
        PARSERS.reduce(nil) do |_, (mode, parser)|
          parsed = parser.parse(expression) rescue next
          @mode = mode
          break parsed
        end
      end

      def transform
        @transform ||= TRANSFORMER.apply(parse, :mode => mode)
      end

      def terms
        @terms ||= if transform.respond_to?(:terms)
          transform.terms
        else
          Array(transform)
        end
      end

    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
unitwise-1.0.3 lib/unitwise/expression/decomposer.rb
unitwise-1.0.2 lib/unitwise/expression/decomposer.rb