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 93 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 49 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 55 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 64 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 70 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 103 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 119 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
Start the translation dance for a (sub)tree. @!visibility private
# File lib/mustermann/ast/translator.rb, line 111 def translate(node, *args, &block) result = decorator_for(node).translate(*args, &block) result = result.node while result.is_a? NodeTranslator result end