class Mustermann::Concat

Class for pattern objects that are a concatenation of other patterns. @see Mustermann::Pattern#+

Public Class Methods

new(*) click to toggle source

Should not be used directly. @!visibility private

Calls superclass method Mustermann::Composite.new
# File lib/mustermann/concat.rb, line 42
def initialize(*)
  super
  AST::Validation.validate(combined_ast) if respond_to? :expand
end

Public Instance Methods

===(string) click to toggle source

@see Mustermann::Pattern#===

# File lib/mustermann/concat.rb, line 54
def ===(string)
  peek_size(string) == string.size
end
expand(behavior = nil, values = {}) click to toggle source

(see Mustermann::Pattern#expand)

# File lib/mustermann/concat.rb, line 89
def expand(behavior = nil, values = {})
  raise NotImplementedError, 'expanding not supported' unless respond_to? :expand
  @expander ||= Mustermann::Expander.new(self) { combined_ast }
  @expander.expand(behavior, values)
end
match(string) click to toggle source

@see Mustermann::Pattern#match

# File lib/mustermann/concat.rb, line 59
def match(string)
  peeked = peek_match(string)
  peeked if peeked.to_s == string
end
operator() click to toggle source

@see Mustermann::Composite#operator @return [Symbol] always :+

# File lib/mustermann/concat.rb, line 49
def operator
  :+
end
params(string) click to toggle source

@see Mustermann::Pattern#params

# File lib/mustermann/concat.rb, line 65
def params(string)
  params, size = peek_params(string)
  params if size == string.size
end
peek_match(string) click to toggle source

@see Mustermann::Pattern#peek_match

# File lib/mustermann/concat.rb, line 76
def peek_match(string)
  pump(string, initial: SimpleMatch.new) do |pattern, substring|
    return unless match = pattern.peek_match(substring)
    [match, match.to_s.size]
  end
end
peek_params(string) click to toggle source

@see Mustermann::Pattern#peek_params

# File lib/mustermann/concat.rb, line 84
def peek_params(string)
  pump(string, inject_with: :merge, with_size: true) { |p, s| p.peek_params(s) }
end
peek_size(string) click to toggle source

@see Mustermann::Pattern#peek_size

# File lib/mustermann/concat.rb, line 71
def peek_size(string)
  pump(string) { |p,s| p.peek_size(s) }
end
respond_to_special?(method) click to toggle source

@!visibility private

# File lib/mustermann/concat.rb, line 102
def respond_to_special?(method)
  method = :to_ast if method.to_sym == :expand
  patterns.all? { |p| p.respond_to?(method) }
end
to_templates() click to toggle source

(see Mustermann::Pattern#to_templates)

# File lib/mustermann/concat.rb, line 96
def to_templates
  raise NotImplementedError, 'template generation not supported' unless respond_to? :to_templates
  @to_templates ||= patterns.inject(['']) { |list, pattern| list.product(pattern.to_templates).map(&:join) }.uniq
end

Private Instance Methods

combined_ast() click to toggle source

generates one big AST from all patterns will not check if patterns support AST generation @!visibility private

# File lib/mustermann/concat.rb, line 128
def combined_ast
  payload = patterns.map { |p| AST::Node[:group].new(p.to_ast.payload) }
  AST::Node[:root].new(payload)
end
pump(string, inject_with: :+, initial: nil, with_size: false) { |pattern, substring| ... } click to toggle source

used to generate results for various methods by scanning through an input string @!visibility private

# File lib/mustermann/concat.rb, line 109
def pump(string, inject_with: :+, initial: nil, with_size: false)
  substring = string
  results   = Array(initial)

  patterns.each do |pattern|
    result, size = yield(pattern, substring)
    return unless result
    results << result
    size    ||= result
    substring = substring[size..-1]
  end

  results = results.inject(inject_with)
  with_size ? [results, string.size - substring.size] : results
end