Class: Mustermann::Concat

Inherits:
Composite show all
Defined in:
mustermann/lib/mustermann/concat.rb

Overview

Class for pattern objects that are a concatenation of other patterns.

See Also:

Constant Summary

Constants included from Mustermann

CompileError, DEFAULT_TYPE, Error, ExpandError, ParseError

Instance Attribute Summary

Attributes inherited from Composite

#patterns

Attributes inherited from Pattern

#uri_decode

Instance Method Summary collapse

Methods inherited from Composite

#==, #eql?, #hash, new, supported?, #to_s

Methods inherited from Pattern

#+, #==, #=~, #eql?, #hash, #named_captures, #names, new, #peek, supported?, supported_options, #to_proc, #to_s, #|

Methods included from Mustermann

[], new

Instance Method Details

#===(string) ⇒ Object

See Also:


55
56
57
# File 'mustermann/lib/mustermann/concat.rb', line 55

def ===(string)
  peek_size(string) == string.size
end

#expand(behavior = nil, values = {}) ⇒ String

Note:

This method is only implemented by certain subclasses.

Expanding is supported by almost all patterns (notable exceptions are Shell, Regular and Simple).

Union Mustermann::Composite patterns (with the | operator) support expanding if all patterns they are composed of also support it.

Examples:

Expanding a pattern

pattern = Mustermann.new('/:name(.:ext)?')
pattern.expand(name: 'hello')             # => "/hello"
pattern.expand(name: 'hello', ext: 'png') # => "/hello.png"

Checking if a pattern supports expanding

if pattern.respond_to? :expand
  pattern.expand(name: "foo")
else
  warn "does not support expanding"
end

Raises:

  • (NotImplementedError)

    raised if expand is not supported.

  • (Mustermann::ExpandError)

    raised if a value is missing or unknown

See Also:


90
91
92
93
94
# File 'mustermann/lib/mustermann/concat.rb', line 90

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) ⇒ Object

See Also:


60
61
62
63
# File 'mustermann/lib/mustermann/concat.rb', line 60

def match(string)
  peeked = peek_match(string)
  peeked if peeked.to_s == string
end

#operatorSymbol

Returns always :+


50
51
52
# File 'mustermann/lib/mustermann/concat.rb', line 50

def operator
  :+
end

#params(string) ⇒ Object

See Also:


66
67
68
69
# File 'mustermann/lib/mustermann/concat.rb', line 66

def params(string)
  params, size = peek_params(string)
  params if size == string.size
end

#peek_match(string) ⇒ Object

See Also:


77
78
79
80
81
82
# File 'mustermann/lib/mustermann/concat.rb', line 77

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) ⇒ Object


85
86
87
# File 'mustermann/lib/mustermann/concat.rb', line 85

def peek_params(string)
  pump(string, inject_with: :merge, with_size: true) { |p, s| p.peek_params(s) }
end

#peek_size(string) ⇒ Object

See Also:


72
73
74
# File 'mustermann/lib/mustermann/concat.rb', line 72

def peek_size(string)
  pump(string) { |p,s| p.peek_size(s) }
end

#to_templatesArray<String>

Note:

This method is only implemented by certain subclasses.

Generates a list of URI template strings representing the pattern.

Note that this transformation is lossy and the strings matching these templates might not match the pattern (and vice versa).

This comes in quite handy since URI templates are not made for pattern matching. That way you can easily use a more precise template syntax and have it automatically generate hypermedia links for you.

Template generation is supported by almost all patterns (notable exceptions are Shell, Regular and Simple). Union Mustermann::Composite patterns (with the | operator) support template generation if all patterns they are composed of also support it.

Examples:

generating templates

Mustermann.new("/:name").to_templates                   # => ["/{name}"]
Mustermann.new("/:foo(@:bar)?/*baz").to_templates       # => ["/{foo}@{bar}/{+baz}", "/{foo}/{+baz}"]
Mustermann.new("/{name}", type: :template).to_templates # => ["/{name}"]

generating templates from composite patterns

pattern  = Mustermann.new('/:name')
pattern |= Mustermann.new('/{name}', type: :template)
pattern |= Mustermann.new('/example/*nested')
pattern.to_templates # => ["/{name}", "/example/{+nested}"]

Checking if a pattern supports expanding

if pattern.respond_to? :to_templates
  pattern.to_templates
else
  warn "does not support template generation"
end

97
98
99
100
# File 'mustermann/lib/mustermann/concat.rb', line 97

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