class Mustermann::AST::Expander
Looks at an AST
, remembers the important bits of information to do an ultra fast expansion.
@!visibility private
Public Instance Methods
Source
# File lib/mustermann/ast/expander.rb, line 80 def add(ast) translate(ast).each do |keys, pattern, filter| self.keys.concat(keys).uniq! mappings[keys.sort] ||= [keys, pattern, filter] end end
add a tree for expansion @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 141 def add_to(list, result) list << [[], ""] if list.empty? list.inject([]) { |l, (k1, p1, f1)| l + result.map { |k2, p2, f2| [k1+k2, p1+p2, f1.merge(f2)] } } end
Creates the product of two of our secret internal data structures. @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 119 def error_for(values) expansions = mappings.keys.map(&:inspect).join(" or ") raise error_class, "cannot expand with keys %p, possible expansions: %s" % [values.keys.sort, expansions] end
helper method for raising an error for unexpandable values @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 126 def escape(string, *args) return super unless string.respond_to?(:=~) # URI::Parser is pretty slow, let's not send every string to it, even if it's unnecessary string =~ /\A\w*\Z/ ? string : super end
Source
# File lib/mustermann/ast/expander.rb, line 95 def expand(values) adjusted = values.each_with_object({}){ |(key, value), new_hash| new_hash[value.instance_of?(Array) ? [key] * value.length : key] = value } keys, pattern, filters = mappings.fetch(adjusted.keys.flatten.sort) { error_for(values) } filters.each { |key, filter| adjusted[key] &&= escape(adjusted[key], also_escape: filter) } pattern % (adjusted[keys] || adjusted.values_at(*keys)) end
@see Mustermann::Pattern#expand
@!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 105 def expandable?(values) values = values.keys if values.respond_to? :keys values = values.sort if values.respond_to? :sort mappings.include? values end
@see Mustermann::Pattern#expandable? @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 113 def expandable_keys(keys) mappings.keys.select { |k| (k - keys).empty? }.max_by(&:size) || keys end
@see Mustermann::Expander#with_rest
@!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 61 def for_capture(node, **options) name = node.name.to_sym pattern('%s', name, name => /(?!#{pattern_for(node, **options)})./) end
helper method for captures @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 74 def keys @keys ||= [] end
all the known keys @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 68 def mappings @mappings ||= {} end
maps sorted key list to sprintf patterns and filters @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 135 def pattern(string = "", *keys, **filters) [[keys, string, filters]] end
Turns a sprintf pattern into our secret internal data structure. @!visibility private
Source
# File lib/mustermann/ast/expander.rb, line 89 def pattern_for(node, **options) Compiler.new.decorator_for(node).pattern(**options) end
helper method for getting a capture’s pattern. @!visibility private