mustermann 3.1.0 → 4.0.0.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -2
- data/README.md +96 -259
- data/lib/mustermann/ast/compiler.rb +124 -29
- data/lib/mustermann/ast/pattern.rb +10 -0
- data/lib/mustermann/ast/translator.rb +7 -2
- data/lib/mustermann/concat.rb +9 -3
- data/lib/mustermann/error.rb +1 -0
- data/lib/mustermann/expander.rb +8 -3
- data/lib/mustermann/hybrid.rb +50 -0
- data/lib/mustermann/match.rb +39 -0
- data/lib/mustermann/pattern.rb +9 -32
- data/lib/mustermann/rails.rb +1 -1
- data/lib/mustermann/regexp_based.rb +22 -7
- data/lib/mustermann/router.rb +99 -0
- data/lib/mustermann/set/cache.rb +30 -0
- data/lib/mustermann/set/linear.rb +30 -0
- data/lib/mustermann/set/match.rb +16 -0
- data/lib/mustermann/set/trie.rb +173 -0
- data/lib/mustermann/set.rb +327 -0
- data/lib/mustermann/sinatra/safe_renderer.rb +1 -1
- data/lib/mustermann/version.rb +1 -1
- data/lib/mustermann.rb +0 -15
- metadata +24 -9
- data/lib/mustermann/extension.rb +0 -3
- data/lib/mustermann/mapper.rb +0 -91
- data/lib/mustermann/pattern_cache.rb +0 -50
- data/lib/mustermann/simple_match.rb +0 -49
- data/lib/mustermann/to_pattern.rb +0 -51
data/lib/mustermann/extension.rb
DELETED
data/lib/mustermann/mapper.rb
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'mustermann'
|
|
3
|
-
require 'mustermann/expander'
|
|
4
|
-
|
|
5
|
-
module Mustermann
|
|
6
|
-
# A mapper allows mapping one string to another based on pattern parsing and expanding.
|
|
7
|
-
#
|
|
8
|
-
# @example
|
|
9
|
-
# require 'mustermann/mapper'
|
|
10
|
-
# mapper = Mustermann::Mapper.new("/:foo" => "/:foo.html")
|
|
11
|
-
# mapper['/example'] # => "/example.html"
|
|
12
|
-
class Mapper
|
|
13
|
-
# Creates a new mapper.
|
|
14
|
-
#
|
|
15
|
-
# @overload initialize(**options)
|
|
16
|
-
# @param options [Hash] options The options hash
|
|
17
|
-
# @yield block for generating mappings as a hash
|
|
18
|
-
# @yieldreturn [Hash] see {#update}
|
|
19
|
-
#
|
|
20
|
-
# @example
|
|
21
|
-
# require 'mustermann/mapper'
|
|
22
|
-
# Mustermann::Mapper.new(type: :rails) {{
|
|
23
|
-
# "/:foo" => ["/:foo.html", "/:foo.:format"]
|
|
24
|
-
# }}
|
|
25
|
-
#
|
|
26
|
-
# @overload initialize(**options)
|
|
27
|
-
# @param options [Hash] options The options hash
|
|
28
|
-
# @yield block for generating mappings as a hash
|
|
29
|
-
# @yieldparam mapper [Mustermann::Mapper] the mapper instance
|
|
30
|
-
#
|
|
31
|
-
# @example
|
|
32
|
-
# require 'mustermann/mapper'
|
|
33
|
-
# Mustermann::Mapper.new(type: :rails) do |mapper|
|
|
34
|
-
# mapper["/:foo"] = ["/:foo.html", "/:foo.:format"]
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
# @overload initialize(map = {}, **options)
|
|
38
|
-
# @param map [Hash] see {#update}
|
|
39
|
-
# @param [Hash] options The options hash
|
|
40
|
-
#
|
|
41
|
-
# @example map before options
|
|
42
|
-
# require 'mustermann/mapper'
|
|
43
|
-
# Mustermann::Mapper.new({"/:foo" => "/:foo.html"}, type: :rails)
|
|
44
|
-
def initialize(map = {}, additional_values: :ignore, **options, &block)
|
|
45
|
-
@map = []
|
|
46
|
-
@options = options
|
|
47
|
-
@additional_values = additional_values
|
|
48
|
-
block.arity == 0 ? update(yield) : yield(self) if block
|
|
49
|
-
update(map) if map
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Add multiple mappings.
|
|
53
|
-
#
|
|
54
|
-
# @param map [Hash{String, Pattern: String, Pattern, Arry<String, Pattern>, Expander}] the mapping
|
|
55
|
-
def update(map)
|
|
56
|
-
map.to_h.each_pair do |input, output|
|
|
57
|
-
input = Mustermann.new(input, **@options)
|
|
58
|
-
output = Expander.new(*output, additional_values: @additional_values, **@options) unless output.is_a? Expander
|
|
59
|
-
@map << [input, output]
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# @return [Hash{Patttern: Expander}] Hash version of the mapper.
|
|
64
|
-
def to_h
|
|
65
|
-
Hash[@map]
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Convert a string according to mappings. You can pass in additional params.
|
|
69
|
-
#
|
|
70
|
-
# @example mapping with and without additional parameters
|
|
71
|
-
# mapper = Mustermann::Mapper.new("/:example" => "(/:prefix)?/:example.html")
|
|
72
|
-
#
|
|
73
|
-
def convert(input, values = {})
|
|
74
|
-
@map.inject(input) do |current, (pattern, expander)|
|
|
75
|
-
params = pattern.params(current)
|
|
76
|
-
params &&= Hash[values.merge(params).map { |k,v| [k.to_s, v] }]
|
|
77
|
-
expander.expandable?(params) ? expander.expand(params) : current
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Add a single mapping.
|
|
82
|
-
#
|
|
83
|
-
# @param key [String, Pattern] format of the input string
|
|
84
|
-
# @param value [String, Pattern, Arry<String, Pattern>, Expander] format of the output string
|
|
85
|
-
def []=(key, value)
|
|
86
|
-
update key => value
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
alias_method :[], :convert
|
|
90
|
-
end
|
|
91
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'set'
|
|
3
|
-
require 'thread'
|
|
4
|
-
require 'mustermann'
|
|
5
|
-
|
|
6
|
-
module Mustermann
|
|
7
|
-
# A simple, persistent cache for creating repositories.
|
|
8
|
-
#
|
|
9
|
-
# @example
|
|
10
|
-
# require 'mustermann/pattern_cache'
|
|
11
|
-
# cache = Mustermann::PatternCache.new
|
|
12
|
-
#
|
|
13
|
-
# # use this instead of Mustermann.new
|
|
14
|
-
# pattern = cache.create_pattern("/:name", type: :rails)
|
|
15
|
-
#
|
|
16
|
-
# @note
|
|
17
|
-
# {Mustermann::Pattern.new} (which is used by {Mustermann.new}) will reuse instances that have
|
|
18
|
-
# not yet been garbage collected. You only need an extra cache if you do not keep a reference to
|
|
19
|
-
# the patterns around.
|
|
20
|
-
#
|
|
21
|
-
# @api private
|
|
22
|
-
class PatternCache
|
|
23
|
-
# @param [Hash] pattern_options default options used for {#create_pattern}
|
|
24
|
-
def initialize(**pattern_options)
|
|
25
|
-
@cached = Set.new
|
|
26
|
-
@mutex = Mutex.new
|
|
27
|
-
@pattern_options = pattern_options
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# @param (see Mustermann.new)
|
|
31
|
-
# @return (see Mustermann.new)
|
|
32
|
-
# @raise (see Mustermann.new)
|
|
33
|
-
# @see Mustermann.new
|
|
34
|
-
def create_pattern(string, **pattern_options)
|
|
35
|
-
pattern = Mustermann.new(string, **pattern_options, **@pattern_options)
|
|
36
|
-
@mutex.synchronize { @cached.add(pattern) } unless @cached.include? pattern
|
|
37
|
-
pattern
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Removes all pattern instances from the cache.
|
|
41
|
-
def clear
|
|
42
|
-
@mutex.synchronize { @cached.clear }
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# @return [Integer] number of currently cached patterns
|
|
46
|
-
def size
|
|
47
|
-
@mutex.synchronize { @cached.size }
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
module Mustermann
|
|
3
|
-
# Fakes MatchData for patterns that do not support capturing.
|
|
4
|
-
# @see http://ruby-doc.org/core-2.0/MatchData.html MatchData
|
|
5
|
-
class SimpleMatch
|
|
6
|
-
# @api private
|
|
7
|
-
def initialize(string = "", names: [], captures: [])
|
|
8
|
-
@string = string.dup
|
|
9
|
-
@names = names
|
|
10
|
-
@captures = captures
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# @return [String] the string that was matched against
|
|
14
|
-
def to_s
|
|
15
|
-
@string.dup
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @return [Array<String>] empty array for imitating MatchData interface
|
|
19
|
-
def names
|
|
20
|
-
@names.dup
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# @return [Array<String>] empty array for imitating MatchData interface
|
|
24
|
-
def captures
|
|
25
|
-
@captures.dup
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# @return [nil] imitates MatchData interface
|
|
29
|
-
def [](*args)
|
|
30
|
-
args.map! do |arg|
|
|
31
|
-
next arg unless arg.is_a? Symbol or arg.is_a? String
|
|
32
|
-
names.index(arg.to_s)
|
|
33
|
-
end
|
|
34
|
-
@captures[*args]
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @!visibility private
|
|
38
|
-
def +(other)
|
|
39
|
-
SimpleMatch.new(@string + other.to_s,
|
|
40
|
-
names: @names + other.names,
|
|
41
|
-
captures: @captures + other.captures)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# @return [String] string representation
|
|
45
|
-
def inspect
|
|
46
|
-
"#<%p %p>" % [self.class, @string]
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'mustermann'
|
|
3
|
-
|
|
4
|
-
module Mustermann
|
|
5
|
-
# Mixin for adding {#to_pattern} ducktyping to objects.
|
|
6
|
-
#
|
|
7
|
-
# @example
|
|
8
|
-
# require 'mustermann/to_pattern'
|
|
9
|
-
#
|
|
10
|
-
# class Foo
|
|
11
|
-
# include Mustermann::ToPattern
|
|
12
|
-
#
|
|
13
|
-
# def to_s
|
|
14
|
-
# ":foo/:bar"
|
|
15
|
-
# end
|
|
16
|
-
# end
|
|
17
|
-
#
|
|
18
|
-
# Foo.new.to_pattern # => #<Mustermann::Sinatra:":foo/:bar">
|
|
19
|
-
#
|
|
20
|
-
# By default included into String, Symbol, Regexp, Array and {Mustermann::Pattern}.
|
|
21
|
-
module ToPattern
|
|
22
|
-
PRIMITIVES = [String, Symbol, Array, Regexp, Mustermann::Pattern]
|
|
23
|
-
private_constant :PRIMITIVES
|
|
24
|
-
|
|
25
|
-
# Converts the object into a {Mustermann::Pattern}.
|
|
26
|
-
#
|
|
27
|
-
# @example converting a string
|
|
28
|
-
# ":name.png".to_pattern # => #<Mustermann::Sinatra:":name.png">
|
|
29
|
-
#
|
|
30
|
-
# @example converting a string with options
|
|
31
|
-
# "/*path".to_pattern(type: :rails) # => #<Mustermann::Rails:"/*path">
|
|
32
|
-
#
|
|
33
|
-
# @example converting a regexp
|
|
34
|
-
# /.*/.to_pattern # => #<Mustermann::Regular:".*">
|
|
35
|
-
#
|
|
36
|
-
# @example converting a pattern
|
|
37
|
-
# Mustermann.new("foo").to_pattern # => #<Mustermann::Sinatra:"foo">
|
|
38
|
-
#
|
|
39
|
-
# @param [Hash] options The options hash.
|
|
40
|
-
# @return [Mustermann::Pattern] pattern corresponding to object.
|
|
41
|
-
def to_pattern(**options)
|
|
42
|
-
input = self if PRIMITIVES.any? { |p| self.is_a? p }
|
|
43
|
-
input ||= __getobj__ if respond_to?(:__getobj__)
|
|
44
|
-
Mustermann.new(input || to_s, **options)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
PRIMITIVES.each do |klass|
|
|
48
|
-
append_features(klass)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|