@@ -5,43 +5,44 @@ class Rule
5
5
attr_reader :options
6
6
7
7
def initialize ( spec , url = nil , options = { } )
8
- @custom_url = url . nil?
8
+ @has_custom_url = url . nil?
9
9
@url = url
10
10
@options = options
11
11
@spec = build_matcher ( spec )
12
12
end
13
13
14
14
def proxy? ( path , *args )
15
- _matches ( path , *args ) . count > 0
15
+ matches ( path , *args ) . any?
16
16
end
17
17
18
- def get_uri ( path , env )
19
- Candidate . new ( self , url , custom_url , path , env ) . build_uri
18
+ def get_uri ( path , env , *args )
19
+ Candidate . new (
20
+ self ,
21
+ has_custom_url ,
22
+ path ,
23
+ env ,
24
+ matches ( path , *args )
25
+ ) . build_uri
20
26
end
21
27
22
28
def to_s
23
29
%("#{ spec } " => "#{ url } ")
24
30
end
25
31
26
- # @private
27
- def _matches ( path , *args )
28
- headers = args [ 0 ]
29
- rackreq = args [ 1 ]
30
- arity = spec . method ( :match ) . arity
31
- if arity == -1
32
- match = spec . match ( path )
33
- else
34
- params = [ path , ( @options [ :accept_headers ] ? headers : nil ) , rackreq ]
35
- match = spec . match ( *params [ 0 ..( arity - 1 ) ] )
36
- end
37
- # FIXME: This state mutation is very confusing
38
- @url = match . url ( path ) if match && custom_url
39
- Array ( match )
40
- end
41
-
42
32
private
43
33
44
- attr_reader :spec , :url , :custom_url
34
+ attr_reader :spec , :url , :has_custom_url
35
+
36
+ def matches ( path , *args )
37
+ Matches . new (
38
+ spec ,
39
+ url ,
40
+ path ,
41
+ options [ :accept_headers ] ,
42
+ has_custom_url ,
43
+ *args
44
+ )
45
+ end
45
46
46
47
def build_matcher ( spec )
47
48
return /^#{ spec } / if spec . is_a? ( String )
@@ -51,13 +52,14 @@ def build_matcher(spec)
51
52
52
53
# Candidate represents a request being matched
53
54
class Candidate
54
- def initialize ( rule , url , custom_url , path , env )
55
+ def initialize ( rule , has_custom_url , path , env , matches )
55
56
@rule = rule
56
57
@env = env
57
58
@path = path
58
- @custom_url = custom_url
59
+ @has_custom_url = has_custom_url
60
+ @matches = matches
59
61
60
- @url = evaluate ( url )
62
+ @url = evaluate ( matches . custom_url )
61
63
end
62
64
63
65
def build_uri
@@ -67,11 +69,11 @@ def build_uri
67
69
68
70
private
69
71
70
- attr_reader :rule , :url , :custom_url , :path , :env
72
+ attr_reader :rule , :url , :has_custom_url , :path , :env , :matches
71
73
72
74
def raw_uri
73
75
return substitute_matches if with_substitutions?
74
- return just_uri if custom_url
76
+ return just_uri if has_custom_url
75
77
uri_with_path
76
78
end
77
79
@@ -98,13 +100,74 @@ def with_substitutions?
98
100
end
99
101
100
102
def substitute_matches
101
- matches . each_with_index . inject ( url ) do |url , ( match , i ) |
102
- url . gsub ( "$#{ i } " , match )
103
+ matches . substitute ( url )
104
+ end
105
+ end
106
+
107
+ # Matches represents collection of matched objects for Rule
108
+ class Matches
109
+ # FIXME: eliminate :url, :accept_headers, :has_custom_url
110
+ def initialize ( spec , url , path , accept_headers , has_custom_url , headers , rackreq , *_ )
111
+ @spec = spec
112
+ @url = url
113
+ @path = path
114
+ @has_custom_url = has_custom_url
115
+ @rackreq = rackreq
116
+
117
+ @headers = headers if accept_headers
118
+ @spec_arity = spec . method ( :match ) . arity
119
+ end
120
+
121
+ def any?
122
+ found . any?
123
+ end
124
+
125
+ def custom_url
126
+ return url unless has_custom_url
127
+ found . map do |match |
128
+ match . url ( path )
129
+ end . first
130
+ end
131
+
132
+ def substitute ( url )
133
+ found . each_with_index . inject ( url ) do |acc , ( match , i ) |
134
+ acc . gsub ( "$#{ i } " , match )
103
135
end
104
136
end
105
137
106
- def matches
107
- rule . _matches ( path )
138
+ private
139
+
140
+ attr_reader :spec , :url , :path , :headers , :rackreq , :spec_arity , :has_custom_url
141
+
142
+ def found
143
+ @_found ||= find_matches
144
+ end
145
+
146
+ def find_matches
147
+ Array (
148
+ spec . match ( *spec_params )
149
+ )
150
+ end
151
+
152
+ def spec_params
153
+ @_spec_params ||= _spec_params
154
+ end
155
+
156
+ def _spec_params
157
+ [
158
+ path ,
159
+ headers ,
160
+ rackreq
161
+ ] [ 0 ...spec_param_count ]
162
+ end
163
+
164
+ def spec_param_count
165
+ @_spec_param_count ||= _spec_param_count
166
+ end
167
+
168
+ def _spec_param_count
169
+ return 1 if spec_arity == -1
170
+ spec_arity
108
171
end
109
172
end
110
173
end
0 commit comments