class Arcana::Rule

Attributes

children[R]
extras[R]
message[R]
offset[R]
pattern[R]

Public Class Methods

new(offset, pattern, message) click to toggle source
# File lib/arcana.rb, line 382
def initialize(offset, pattern, message)
  @offset = offset
  @pattern = pattern
  @message = message
  @extras = {}
  @children = []
end

Public Instance Methods

inspect() click to toggle source
# File lib/arcana.rb, line 436
def inspect
  "<#{self.class} #{@offset} #{@pattern.inspect} #{@message}>"
end
match(input, match) click to toggle source
# File lib/arcana.rb, line 390
def match(input, match)
  return EMPTY_ARRAY if @offset.relative?
  #return EMPTY_ARRAY unless @offset.exact?
  ruleset = match.ruleset

  input = Cursor.new(input) unless Cursor === input
  @offset.seek(input)

  if pattern.type == "use"
    return EMPTY_ARRAY if pattern.value.start_with?("\\^") # FIXME: endianness swap
    use = ruleset.names.fetch(pattern.value)
    input.restore do
      input.mark_base # FIXME: no idea if this works
      return use.visit_children(input, match)
    end
  elsif pattern.type == "indirect"
    # FIXME: do this better
    original_input = input.buf
    return match.ruleset.match(original_input[input.offset..], match)
  end

  if @pattern.match?(input)
    match = match.add(self)
    child_matches = visit_children(input, match)
    if child_matches.any?
      child_matches
    else
      match
    end
  else
    EMPTY_ARRAY
  end
end
mime_type() click to toggle source
# File lib/arcana.rb, line 432
def mime_type
  @extras["mime"]
end
visit_children(input, match) click to toggle source
# File lib/arcana.rb, line 424
def visit_children(input, match)
  children.flat_map do |child|
    input.restore do
      child.match(input, match)
    end
  end
end