class Mustermann::AST::Translator

Implements translator pattern

@abstract @!visibility private

Public Class Methods

create(&block) click to toggle source

Enables quick creation of a translator object.

@example

require 'mustermann'
require 'mustermann/ast/translator'

translator = Mustermann::AST::Translator.create do
  translate(:node)  { [type, *t(payload)].flatten.compact }
  translate(Array)  { map { |e| t(e) } }
  translate(Object) { }
end

ast = Mustermann.new('/:name').to_ast
translator.translate(ast) # => [:root, :separator, :capture]

@!visibility private

# File lib/mustermann/ast/translator.rb, line 95
def self.create(&block)
  Class.new(self, &block).new
end
dispatch_table() click to toggle source

maps types to translations @!visibility private

# File lib/mustermann/ast/translator.rb, line 51
def self.dispatch_table
  @dispatch_table ||= {}
end
inherited(subclass) click to toggle source

some magic sauce so {NodeTranslator}s know whom to talk to for {#register} @!visibility private

Calls superclass method
# File lib/mustermann/ast/translator.rb, line 57
def self.inherited(subclass)
  node_translator = Class.new(NodeTranslator)
  node_translator.define_singleton_method(:translator) { subclass }
  subclass.const_set(:NodeTranslator, node_translator)
  super
end
raises(error) click to toggle source

DSL-ish method for specifying the exception class to use. @!visibility private

# File lib/mustermann/ast/translator.rb, line 66
def self.raises(error)
  define_method(:error_class) { error }
end
translate(*types, &block) click to toggle source

DSL method for defining single method translations. @!visibility private

# File lib/mustermann/ast/translator.rb, line 72
def self.translate(*types, &block)
  Class.new(const_get(:NodeTranslator)) do
    register(*types)
    define_method(:translate, &block)
  end
end

Public Instance Methods

decorator_for(node) click to toggle source

@param [Mustermann::AST::Node, Object] node to translate @return decorator encapsulating translation

@!visibility private

# File lib/mustermann/ast/translator.rb, line 105
def decorator_for(node)
  factory = node.class.ancestors.inject(nil) { |d,a| d || self.class.dispatch_table[a.name] }
  raise error_class, "#{self.class}: Cannot translate #{node.class}" unless factory
  factory.new(node, self)
end
escape(char, parser: URI::DEFAULT_PARSER, escape: parser.regexp[:UNSAFE], also_escape: nil) click to toggle source

@return [String] escaped character @!visibility private

# File lib/mustermann/ast/translator.rb, line 121
def escape(char, parser: URI::DEFAULT_PARSER, escape: parser.regexp[:UNSAFE], also_escape: nil)
  escape = Regexp.union(also_escape, escape) if also_escape
  char =~ escape ? parser.escape(char, Regexp.union(*escape)) : char
end
translate(node, *args, &block) click to toggle source
# File lib/mustermann/ast/translator.rb, line 113
               def translate(node, *args, &block)
  result = decorator_for(node).translate(*args, &block)
  result = result.node while result.is_a? NodeTranslator
  result
end