Class: Arcana::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/arcana.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(offset, pattern, message) ⇒ Rule

Returns a new instance of Rule.



382
383
384
385
386
387
388
# File 'lib/arcana.rb', line 382

def initialize(offset, pattern, message)
  @offset = offset
  @pattern = pattern
  @message = message
  @extras = {}
  @children = []
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



380
381
382
# File 'lib/arcana.rb', line 380

def children
  @children
end

#extrasObject (readonly)

Returns the value of attribute extras.



380
381
382
# File 'lib/arcana.rb', line 380

def extras
  @extras
end

#messageObject (readonly)

Returns the value of attribute message.



380
381
382
# File 'lib/arcana.rb', line 380

def message
  @message
end

#offsetObject (readonly)

Returns the value of attribute offset.



380
381
382
# File 'lib/arcana.rb', line 380

def offset
  @offset
end

#patternObject (readonly)

Returns the value of attribute pattern.



380
381
382
# File 'lib/arcana.rb', line 380

def pattern
  @pattern
end

Instance Method Details

#inspectObject



436
437
438
# File 'lib/arcana.rb', line 436

def inspect
  "<#{self.class} #{@offset} #{@pattern.inspect} #{@message}>"
end

#match(input, match) ⇒ Object



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# 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_typeObject



432
433
434
# File 'lib/arcana.rb', line 432

def mime_type
  @extras["mime"]
end

#visit_children(input, match) ⇒ Object



424
425
426
427
428
429
430
# 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