-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
pattern.rb
81 lines (66 loc) · 2.09 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
77
78
79
80
81
# 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, :params
def_delegators :to_regexp, :===
alias match? ===
def initialize(origin, suffix, options)
@origin = origin
@path = build_path(origin, options[:anchor], suffix)
@pattern = build_pattern(@path, options[:params], options[:format], options[:version], options[:requirements])
@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, params, format, version, requirements)
Mustermann::Grape.new(
path,
uri_decode: true,
params: params,
capture: extract_capture(format, version, requirements)
)
end
def build_path(pattern, anchor, suffix)
PatternCache[[build_path_from_pattern(pattern, anchor), suffix]]
end
def extract_capture(format, version, requirements)
capture = {}.tap do |h|
h[:format] = map_str(format) if format.present?
h[:version] = map_str(version) if version.present?
end
return capture if requirements.blank?
requirements.merge(capture)
end
def build_path_from_pattern(pattern, anchor)
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
def map_str(value)
Array.wrap(value).map(&:to_s)
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