forked from ruby-grape/grape
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpattern.rb
76 lines (63 loc) · 2.04 KB
/
pattern.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# frozen_string_literal: true
module Grape
class Router
class Pattern
extend Forwardable
DEFAULT_CAPTURES = %w[format version].freeze
attr_reader :origin, :path, :pattern, :to_regexp
def_delegators :pattern, :named_captures, :params
def_delegators :to_regexp, :===
alias match? ===
def initialize(pattern, **options)
@origin = pattern
@path = build_path(pattern, anchor: options[:anchor], suffix: options[:suffix])
@pattern = build_pattern(@path, options)
@to_regexp = @pattern.to_regexp
end
def captures_default
to_regexp.names
.delete_if { |n| DEFAULT_CAPTURES.include?(n) }
.to_h { |k| [k, ''] }
end
private
def build_pattern(path, options)
Mustermann::Grape.new(
path,
uri_decode: true,
params: options[:params],
capture: extract_capture(**options)
)
end
def build_path(pattern, anchor: false, suffix: nil)
PatternCache[[build_path_from_pattern(pattern, anchor: anchor), suffix]]
end
def extract_capture(**options)
sliced_options = options
.slice(:format, :version)
.delete_if { |_k, v| v.blank? }
.transform_values { |v| Array.wrap(v).map(&:to_s) }
return sliced_options if options[:requirements].blank?
options[:requirements].merge(sliced_options)
end
def build_path_from_pattern(pattern, anchor: false)
if pattern.end_with?('*path')
pattern.dup.insert(pattern.rindex('/') + 1, '?')
elsif anchor
pattern
elsif pattern.end_with?('/')
"#{pattern}?*path"
else
"#{pattern}/?*path"
end
end
class PatternCache < Grape::Util::Cache
def initialize
super
@cache = Hash.new do |h, (pattern, suffix)|
h[[pattern, suffix]] = -"#{pattern}#{suffix}"
end
end
end
end
end
end