Class: Mustermann::Composite

Inherits:
Pattern
  • Object
show all
Defined in:
mustermann/lib/mustermann/composite.rb

Overview

Class for pattern objects composed of multiple patterns using binary logic.

Direct Known Subclasses

Concat

Constant Summary

Constants included from Mustermann

CompileError, DEFAULT_TYPE, Error, ExpandError, ParseError

Instance Attribute Summary collapse

Attributes inherited from Pattern

#uri_decode

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Pattern

#+, #=~, #named_captures, #names, #peek, #peek_match, #peek_params, #peek_size, supported_options, #to_proc, #|

Methods included from Mustermann

[]

Constructor Details

#initialize(patterns, operator: :|, **options) ⇒ Composite

Returns a new instance of Composite


27
28
29
30
# File 'mustermann/lib/mustermann/composite.rb', line 27

def initialize(patterns, operator: :|, **options)
  @operator = operator.to_sym
  @patterns = patterns.flat_map { |p| patterns_from(p, **options) }
end

Instance Attribute Details

#operatorObject (readonly)

Returns the value of attribute operator


8
9
10
# File 'mustermann/lib/mustermann/composite.rb', line 8

def operator
  @operator
end

#patternsObject (readonly)

Returns the value of attribute patterns


8
9
10
# File 'mustermann/lib/mustermann/composite.rb', line 8

def patterns
  @patterns
end

Class Method Details

.new(*patterns, **options) ⇒ Mustermann::Pattern

Returns a new composite pattern

Returns:


18
19
20
21
22
23
24
25
# File 'mustermann/lib/mustermann/composite.rb', line 18

def self.new(*patterns, **options)
  patterns = patterns.flatten
  case patterns.size
  when 0 then raise ArgumentError, 'cannot create empty composite pattern'
  when 1 then patterns.first
  else super(patterns, **options)
  end
end

.supported?(option, type: nil, **options) ⇒ Boolean

Returns:

  • (Boolean)

See Also:


12
13
14
15
# File 'mustermann/lib/mustermann/composite.rb', line 12

def self.supported?(option, type: nil, **options)
  return true if super
  Mustermann[type || Mustermann::DEFAULT_TYPE].supported?(option, **options)
end

Instance Method Details

#==(pattern) ⇒ Object

See Also:


33
34
35
# File 'mustermann/lib/mustermann/composite.rb', line 33

def ==(pattern)
  patterns == patterns_from(pattern)
end

#===(string) ⇒ Object

See Also:


48
49
50
# File 'mustermann/lib/mustermann/composite.rb', line 48

def ===(string)
  patterns.map { |p| p === string }.inject(operator)
end

#eql?(pattern) ⇒ Boolean

Returns:

  • (Boolean)

See Also:


38
39
40
# File 'mustermann/lib/mustermann/composite.rb', line 38

def eql?(pattern)
  patterns.eql? patterns_from(pattern)
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

Parameters:

  • behavior (Symbol) (defaults to: nil)

    What to do with additional key/value pairs not present in the values hash. Possible options: :raise, :ignore, :append.

  • values (Hash{Symbol: #to_s, Array<#to_s>}) (defaults to: {})

    Values to use for expansion.

Returns:

  • (String)

    expanded string

Raises:

  • (NotImplementedError)

    raised if expand is not supported.

  • (Mustermann::ExpandError)

    raised if a value is missing or unknown

See Also:


69
70
71
72
73
# File 'mustermann/lib/mustermann/composite.rb', line 69

def expand(behavior = nil, values = {})
  raise NotImplementedError, 'expanding not supported' unless respond_to? :expand
  @expander ||= Mustermann::Expander.new(*patterns)
  @expander.expand(behavior, values)
end

#hashObject

See Also:


43
44
45
# File 'mustermann/lib/mustermann/composite.rb', line 43

def hash
  patterns.hash | operator.hash
end

#match(string) ⇒ Object

See Also:


58
59
60
# File 'mustermann/lib/mustermann/composite.rb', line 58

def match(string)
  with_matching(string, :match)
end

#params(string) ⇒ Object

See Also:


53
54
55
# File 'mustermann/lib/mustermann/composite.rb', line 53

def params(string)
  with_matching(string, :params)
end

#to_sString

Returns the string representation of the pattern

Returns:

  • (String)

    the string representation of the pattern


82
83
84
# File 'mustermann/lib/mustermann/composite.rb', line 82

def to_s
  simple_inspect
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

Returns:

  • (Array<String>)

    list of URI templates

Raises:

  • (NotImplementedError)

76
77
78
79
# File 'mustermann/lib/mustermann/composite.rb', line 76

def to_templates
  raise NotImplementedError, 'template generation not supported' unless respond_to? :to_templates
  patterns.flat_map(&:to_templates).uniq
end