class Repeatable::Parser

Attributes

hash[R]

Public Class Methods

call(hash) click to toggle source
# File lib/repeatable/parser.rb, line 7
def self.call(hash)
  new(hash).call
end
new(hash) click to toggle source
# File lib/repeatable/parser.rb, line 3
def initialize(hash)
  @hash = hash
end

Public Instance Methods

call() click to toggle source
# File lib/repeatable/parser.rb, line 11
def call
  build_expression(hash)
end

Private Instance Methods

build_expression(hash) click to toggle source
# File lib/repeatable/parser.rb, line 19
def build_expression(hash)
  if hash.length != 1
    fail(ParseError, "Invalid expression: '#{hash}' must have single key and value")
  else
    expression_for(*hash.first)
  end
end
expression_for(key, value) click to toggle source
# File lib/repeatable/parser.rb, line 27
def expression_for(key, value)
  klass = expression_klass(key.to_s)
  case klass
  when nil
    fail(ParseError, "Unknown mapping: Can't map key '#{key.inspect}' to an expression class")
  when Repeatable::Expression::Set
    args = value.map { |hash| build_expression(hash) }
    klass.new(*args)
  when Repeatable::Expression::Difference
    value = symbolize_keys(value)
    klass.new(
      included: build_expression(value[:included]),
      excluded: build_expression(value[:excluded])
    )
  else
    klass.new(**symbolize_keys(value))
  end
end
expression_klass(string) click to toggle source
# File lib/repeatable/parser.rb, line 50
def expression_klass(string)
  camel_cased_string = string
    .capitalize
    .gsub(/(?:_)(?<word>[a-z\d]+)/i) { Regexp.last_match[:word].capitalize }
  Repeatable::Expression.const_get(camel_cased_string)
rescue NameError => e
  raise if e.name && e.name.to_s != camel_cased_string
end
symbolize_keys(hash) click to toggle source
# File lib/repeatable/parser.rb, line 46
def symbolize_keys(hash)
  hash.each_with_object({}) { |(k, v), a| a[k.to_sym] = v }
end