commute 0.2.0.rc.2 → 0.3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.todo +28 -12
- data/README.md +0 -1
- data/commute.gemspec +4 -5
- data/lib/commute/common/basic_auth.rb +10 -9
- data/lib/commute/common/caching.rb +208 -0
- data/lib/commute/common/chemicals.rb +47 -24
- data/lib/commute/common/eventmachine.rb +68 -0
- data/lib/commute/common/synchrony.rb +42 -0
- data/lib/commute/common/typhoeus.rb +64 -0
- data/lib/commute/core/api.rb +42 -29
- data/lib/commute/core/builder.rb +4 -15
- data/lib/commute/core/context.rb +156 -15
- data/lib/commute/core/http.rb +124 -0
- data/lib/commute/core/layer.rb +187 -0
- data/lib/commute/core/sequence.rb +83 -132
- data/lib/commute/core/stack.rb +63 -72
- data/lib/commute/core/status.rb +45 -0
- data/lib/commute/core/util/event_emitter.rb +58 -0
- data/lib/commute/core/util/path.rb +37 -0
- data/lib/commute/core/util/stream.rb +141 -0
- data/lib/commute/extensions/crud.rb +88 -0
- data/lib/commute/extensions/param.rb +20 -0
- data/lib/commute/extensions/url.rb +53 -0
- data/lib/commute/version.rb +1 -1
- data/spec/commute/common/caching_spec.rb +158 -0
- data/spec/commute/common/eventmachine_spec.rb +74 -0
- data/spec/commute/common/typhoeus_spec.rb +67 -0
- data/spec/commute/core/api_spec.rb +3 -1
- data/spec/commute/core/builder_spec.rb +8 -8
- data/spec/commute/core/http_spec.rb +39 -0
- data/spec/commute/core/layer_spec.rb +81 -0
- data/spec/commute/core/sequence_spec.rb +36 -150
- data/spec/commute/core/stack_spec.rb +33 -83
- data/spec/commute/core/util/event_emitter_spec.rb +35 -0
- data/spec/commute/core/util/path_spec.rb +29 -0
- data/spec/commute/core/util/stream_spec.rb +90 -0
- data/spec/commute/extensions/url_spec.rb +76 -0
- data/spec/spec_helper.rb +3 -1
- metadata +61 -48
- data/examples/gist_api.rb +0 -71
- data/examples/highrise_task_api.rb +0 -59
- data/examples/pastie_api.rb +0 -18
- data/lib/commute/aspects/caching.rb +0 -37
- data/lib/commute/aspects/crud.rb +0 -41
- data/lib/commute/aspects/pagination.rb +0 -16
- data/lib/commute/aspects/url.rb +0 -57
- data/lib/commute/common/cache.rb +0 -43
- data/lib/commute/common/conditional.rb +0 -27
- data/lib/commute/common/em-synchrony_adapter.rb +0 -29
- data/lib/commute/common/em_http_request_adapter.rb +0 -57
- data/lib/commute/common/typhoeus_adapter.rb +0 -40
- data/lib/commute/common/xml.rb +0 -7
- data/lib/commute/core/commuter.rb +0 -116
- data/lib/commute/core/processors/code_status_processor.rb +0 -40
- data/lib/commute/core/processors/hook.rb +0 -14
- data/lib/commute/core/processors/request_builder.rb +0 -26
- data/lib/commute/core/processors/sequencer.rb +0 -46
- data/lib/commute/core/request.rb +0 -58
- data/lib/commute/core/response.rb +0 -18
- data/spec/commute/aspects/caching_spec.rb +0 -12
- data/spec/commute/aspects/url_spec.rb +0 -61
- data/spec/commute/core/commuter_spec.rb +0 -64
- data/spec/commute/core/processors/code_status_processor_spec.rb +0 -5
- data/spec/commute/core/processors/hook_spec.rb +0 -25
- data/spec/commute/core/processors/request_builder_spec.rb +0 -25
- data/spec/commute/core/processors/sequencer_spec.rb +0 -33
data/lib/commute/core/builder.rb
CHANGED
@@ -54,7 +54,7 @@ module Commute
|
|
54
54
|
end
|
55
55
|
|
56
56
|
# Public: Adds logical parameters to the context.
|
57
|
-
#
|
57
|
+
# Logical parameters whose names match the id of a
|
58
58
|
# layer, get passed to that layer as options.
|
59
59
|
#
|
60
60
|
# When a parameter is set to nil, it is excluded
|
@@ -188,7 +188,7 @@ module Commute
|
|
188
188
|
end
|
189
189
|
|
190
190
|
# Same as `transform` but removes all existing transformations for these dependencies.
|
191
|
-
def transform! *dependencies, &transformation
|
191
|
+
def transform! name, *dependencies, &transformation
|
192
192
|
end
|
193
193
|
|
194
194
|
# Public: Used to alter the stack or one of its sequences.
|
@@ -233,19 +233,8 @@ module Commute
|
|
233
233
|
end
|
234
234
|
end
|
235
235
|
|
236
|
-
|
237
|
-
|
238
|
-
with limit: max
|
239
|
-
end
|
240
|
-
|
241
|
-
# TODO
|
242
|
-
def offset index
|
243
|
-
with offset: index
|
244
|
-
end
|
245
|
-
|
246
|
-
# TODO
|
247
|
-
def order field, direction = :asc
|
248
|
-
with order: { field: field, direction: direction }
|
236
|
+
def body body
|
237
|
+
with! body: body
|
249
238
|
end
|
250
239
|
|
251
240
|
private
|
data/lib/commute/core/context.rb
CHANGED
@@ -2,14 +2,61 @@ require 'forwardable'
|
|
2
2
|
|
3
3
|
require 'commute/core/builder'
|
4
4
|
require 'commute/core/stack'
|
5
|
-
require 'commute/core/
|
5
|
+
require 'commute/core/http'
|
6
6
|
|
7
|
+
# A context is a snapshot of a builder. It holds partial
|
8
|
+
# information on how to build and execute a request.
|
9
|
+
#
|
10
|
+
# This is:
|
11
|
+
# * A stack
|
12
|
+
# * Logical parameters
|
13
|
+
# * Transformation that transform logical parameters into request parameters
|
14
|
+
# * Disables (for skipping layers)
|
15
|
+
#
|
16
|
+
# When a context holds enough information to execute a request, you
|
17
|
+
# can execute it in 6 different ways (depending on your adapter):
|
18
|
+
#
|
19
|
+
# 1) Run Synchronously.
|
20
|
+
# paste, status[, response] = pastes.find(1).run
|
21
|
+
# pasted, status[, response] = api.create.run("Some paste")
|
22
|
+
# # OR
|
23
|
+
# pasted, status[, response] = api.put.one.run("Some paste")
|
24
|
+
#
|
25
|
+
# 2) Run Synchronously unsafe
|
26
|
+
# paste = pasted.find(1).run!
|
27
|
+
#
|
28
|
+
# 3) Run Asynchronously.
|
29
|
+
# pastes.find(1).run { |paste[, status[, response]]| ... }
|
30
|
+
#
|
31
|
+
# 4) Stream (down)
|
32
|
+
# pastes.all.stream { |response, status|
|
33
|
+
# # Received a response.
|
34
|
+
# response.on(:data) { |paste| ... }
|
35
|
+
# response.on(:end) { ... }
|
36
|
+
# }
|
37
|
+
#
|
38
|
+
# 5) Stream unsafe (down)
|
39
|
+
# pastes.all.stream! { |paste|
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# 6) The full treatment (up and downstreaming)
|
43
|
+
# request = pastes.all.request { |response, status|
|
44
|
+
# }
|
45
|
+
# request.write ...
|
46
|
+
# request.end
|
47
|
+
#
|
7
48
|
module Commute
|
8
49
|
class Context
|
9
50
|
include Buildable
|
10
51
|
|
52
|
+
# Public: All information needed to build and execute a request.
|
11
53
|
attr_reader :stack, :parameters, :transformations, :disables
|
12
54
|
|
55
|
+
# Internal: Creates a new context. A developer never has to call
|
56
|
+
# this method manually.
|
57
|
+
#
|
58
|
+
# It sets up a snapshot of a builder and freezes all information.
|
59
|
+
#
|
13
60
|
def initialize stack = nil, parameters = {}, transformations = [], \
|
14
61
|
disables = [], builder_class = Builder
|
15
62
|
@stack = stack.freeze
|
@@ -19,32 +66,111 @@ module Commute
|
|
19
66
|
@builder_class = builder_class
|
20
67
|
end
|
21
68
|
|
69
|
+
# Public: Get a logical parameter.
|
70
|
+
#
|
71
|
+
# key - The key of the logical parameter.
|
72
|
+
#
|
73
|
+
# Returns the value of the logical parameter.
|
22
74
|
def [] key
|
23
75
|
@parameters[key]
|
24
76
|
end
|
25
77
|
|
26
|
-
# Public:
|
78
|
+
# Public: Check if a layer is enabled.
|
27
79
|
#
|
80
|
+
# name - The name of the layer in question.
|
81
|
+
#
|
82
|
+
# Returns `true` if the layer is enabled in the current context.
|
83
|
+
def enabled? name
|
84
|
+
!disables.include?(name)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Internal: Creates a new context, resetting all transformations.
|
28
88
|
def reset
|
89
|
+
self.class.new stack, parameters, [], disables, builder_class
|
29
90
|
end
|
30
91
|
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
92
|
+
# Public: Down and Upstream any content (safely).
|
93
|
+
# The Full Treatment.
|
94
|
+
#
|
95
|
+
# Yields Layer Response and a status.
|
96
|
+
# Returns a Layer Request.
|
97
|
+
#
|
98
|
+
def request &on_response
|
99
|
+
@stack.call self.build, &on_response
|
37
100
|
end
|
38
101
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
102
|
+
# Public: Downstream any remote content (safely).
|
103
|
+
#
|
104
|
+
# body - Optional body to send with the request.
|
105
|
+
#
|
106
|
+
# Yields a Layer Response and a status.
|
107
|
+
# Returns Nothing.
|
108
|
+
#
|
109
|
+
def stream body = self[:body], &on_response
|
110
|
+
self.request(&on_response).tap do |request|
|
111
|
+
request.write body if body
|
112
|
+
request.end
|
45
113
|
end
|
114
|
+
# Return Nothing.
|
115
|
+
nil
|
46
116
|
end
|
47
117
|
|
118
|
+
# Public: Downstream any remote content (unsafely).
|
119
|
+
#
|
120
|
+
# body - Optional body to send with the request.
|
121
|
+
#
|
122
|
+
# Yields for every chunk of body/result streamed.
|
123
|
+
# Returns Nothing.
|
124
|
+
#
|
125
|
+
def stream! body = self[:body], &on_data
|
126
|
+
self.stream do |response, status|
|
127
|
+
response.on :end, &on_data
|
128
|
+
end
|
129
|
+
# Return Nothing.
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
|
133
|
+
# Public: Run (a)synchronously, only returns if data is fully
|
134
|
+
# received. Direct return only possible with synchronous adapter.
|
135
|
+
#
|
136
|
+
# body - Optional body to send with the request.
|
137
|
+
#
|
138
|
+
# Yields the buffered data, status and response. (sync)
|
139
|
+
# Returns the buffered data, status and response. (sync/async)
|
140
|
+
#
|
141
|
+
def run body = self[:body], &on_result
|
142
|
+
# Temprary result variable in this scope.
|
143
|
+
result, status, response = nil, nil, nil
|
144
|
+
# Stream the response.
|
145
|
+
self.stream(body) do |_response, _status|
|
146
|
+
# Set status.
|
147
|
+
status, response = _status, _response
|
148
|
+
# Buffer all data in result.
|
149
|
+
response.once(:data) { |_result| result = _result }
|
150
|
+
# Call on_result in the end.
|
151
|
+
response.on(:end) do
|
152
|
+
on_result.call result, status, response if on_result
|
153
|
+
end
|
154
|
+
end
|
155
|
+
# Also just return the result.
|
156
|
+
return result, status, response
|
157
|
+
end
|
158
|
+
|
159
|
+
# Public: Run synchronously unsafe.
|
160
|
+
# Only returns data when fully buffered, without a status.
|
161
|
+
#
|
162
|
+
# body - Optional body to send with the request.
|
163
|
+
#
|
164
|
+
# Returns the buffered data.
|
165
|
+
#
|
166
|
+
def run! body = self[:body]
|
167
|
+
return self.run(body).first
|
168
|
+
end
|
169
|
+
|
170
|
+
# Internal: Methods not defined on Context trigger
|
171
|
+
# the creation of a builder.
|
172
|
+
#
|
173
|
+
# The method is then forwarded to the builder.
|
48
174
|
def method_missing method, *args, &block
|
49
175
|
b = builder
|
50
176
|
if b.respond_to?(method)
|
@@ -54,8 +180,23 @@ module Commute
|
|
54
180
|
end
|
55
181
|
end
|
56
182
|
|
57
|
-
|
183
|
+
protected
|
58
184
|
|
185
|
+
# Internal: Build a Http Request using context transformations.
|
186
|
+
#
|
187
|
+
def build
|
188
|
+
# Create a new request.
|
189
|
+
http_request = Http::Request.new(self)
|
190
|
+
# Build the request using context transformations.
|
191
|
+
@transformations.each do |t|
|
192
|
+
t.call http_request, self
|
193
|
+
end
|
194
|
+
# Return the http request.
|
195
|
+
http_request
|
196
|
+
end
|
197
|
+
|
198
|
+
# Internal: Creates a new Builder for this context.
|
199
|
+
#
|
59
200
|
def builder
|
60
201
|
@builder_class.new self
|
61
202
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
require 'commute/core/status'
|
4
|
+
|
5
|
+
module Commute
|
6
|
+
|
7
|
+
# Collection of model classes associated with Http.
|
8
|
+
module Http
|
9
|
+
|
10
|
+
# Public: Status that derives its ok status from a given
|
11
|
+
# Http status code.
|
12
|
+
#
|
13
|
+
class Status < Commute::Status
|
14
|
+
attr_reader :code
|
15
|
+
|
16
|
+
# Public: Creates a new Http Status.
|
17
|
+
#
|
18
|
+
# code - Http Status code.
|
19
|
+
# error - Optional error details (Can be anything).
|
20
|
+
#
|
21
|
+
def initialize code, error = nil
|
22
|
+
super !(400..599).include?(code)
|
23
|
+
@code = code
|
24
|
+
end
|
25
|
+
|
26
|
+
def not_modified?
|
27
|
+
@code == 304
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public: A Http connection to a host/port with a certain protocol.
|
32
|
+
class Connection
|
33
|
+
|
34
|
+
# Public: Uri of the host (containing scheme, host and port).
|
35
|
+
attr_reader :uri
|
36
|
+
end
|
37
|
+
|
38
|
+
# Public: A Http Request.
|
39
|
+
class Request
|
40
|
+
|
41
|
+
# Public: The context in which the Http Request is made.
|
42
|
+
attr_reader :context
|
43
|
+
|
44
|
+
# Public: Uri of EATS (Everything after the slash).
|
45
|
+
attr_accessor :uri
|
46
|
+
|
47
|
+
# Public: Url parameters (Hash).
|
48
|
+
attr_accessor :query
|
49
|
+
alias :params :query
|
50
|
+
alias :params= :query=
|
51
|
+
|
52
|
+
# Public: The HTTP Method of the request (Symbol).
|
53
|
+
# Mostly :get, :post, :put, :patch, :delete
|
54
|
+
attr_accessor :method
|
55
|
+
|
56
|
+
# Public: Request headers.
|
57
|
+
attr_accessor :headers
|
58
|
+
|
59
|
+
# Public: Optional connection associated with this request.
|
60
|
+
attr_reader :connection
|
61
|
+
|
62
|
+
# Public: Initializes a new Http Request with some default values.
|
63
|
+
#
|
64
|
+
# context - The context in which the Http Request is made.
|
65
|
+
#
|
66
|
+
def initialize context
|
67
|
+
@context = context
|
68
|
+
@uri = URI::Generic.build path: '/'
|
69
|
+
@headers = {}
|
70
|
+
@query = {}
|
71
|
+
@method = :get
|
72
|
+
end
|
73
|
+
|
74
|
+
# Public: Getting the Http method.
|
75
|
+
#
|
76
|
+
# Overload the default reader method for overloading
|
77
|
+
# of Object#method.
|
78
|
+
#
|
79
|
+
def method name = nil
|
80
|
+
name.nil? ? @method : super(name)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Public: Get the URI of the Request.
|
84
|
+
#
|
85
|
+
# Override the default reader method for consistency
|
86
|
+
# with the query setter method on Request.
|
87
|
+
# We first merge the query string into the URI before
|
88
|
+
# returning it.
|
89
|
+
#
|
90
|
+
def uri
|
91
|
+
@uri.query = URI.encode_www_form_component( \
|
92
|
+
URI.encode_www_form(self.query)
|
93
|
+
) if !self.query.empty?
|
94
|
+
@uri
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Public: An Http Response.
|
99
|
+
class Response
|
100
|
+
|
101
|
+
# Public: The request responsible for this response.
|
102
|
+
attr_accessor :request
|
103
|
+
|
104
|
+
# Public: Http Response code.
|
105
|
+
attr_accessor :code
|
106
|
+
|
107
|
+
# Public: Request headers.
|
108
|
+
attr_accessor :headers
|
109
|
+
|
110
|
+
# Public: Initializes a new Http Response with a reference Request.
|
111
|
+
#
|
112
|
+
# request - The request responsible for this response.
|
113
|
+
#
|
114
|
+
def initialize request
|
115
|
+
@request = request
|
116
|
+
@headers = {}
|
117
|
+
end
|
118
|
+
|
119
|
+
def etag
|
120
|
+
headers['ETag']
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'commute/core/util/event_emitter'
|
2
|
+
require 'commute/core/util/stream'
|
3
|
+
|
4
|
+
module Commute
|
5
|
+
|
6
|
+
# Internal: A Layer is one processing piece in a commute stack.
|
7
|
+
#
|
8
|
+
# A layer acts as a mini in-process server that takes its own
|
9
|
+
# requests (Layer::Request) and issues its own requests (to the
|
10
|
+
# next layer in the stack). Therefor implementing a layer
|
11
|
+
# gives you alot of rope to work with.
|
12
|
+
#
|
13
|
+
# Think of layers as seperate network components that call
|
14
|
+
# each other in a russian-doll model with the adapter as
|
15
|
+
# the most inner doll.
|
16
|
+
#
|
17
|
+
# The Layer requests and response are only for communication
|
18
|
+
# between the layers, they carry the real http requests
|
19
|
+
# and responses (access at Request#http and Response#http).
|
20
|
+
#
|
21
|
+
# The Spec for a layer is documented hereafter.
|
22
|
+
#
|
23
|
+
# A layer implements a call method that takes a router, request
|
24
|
+
# and some options from the context of that request
|
25
|
+
# meant for the layer.
|
26
|
+
#
|
27
|
+
# The router is a the router that a connects all layers of
|
28
|
+
# stack needed for this request.
|
29
|
+
#
|
30
|
+
# Take a simple layer that does not call the next layer,
|
31
|
+
# but just echoes all that is sent to it.
|
32
|
+
#
|
33
|
+
# def call router, request, options = {
|
34
|
+
# # Respond to the request right away.
|
35
|
+
# response = request.respond Response.new, Status.ok
|
36
|
+
# # Echo all data.
|
37
|
+
# request.on(:data) do |chunk|
|
38
|
+
# response.write chunk
|
39
|
+
# end
|
40
|
+
# # When the request ends, we also have no use anymore.
|
41
|
+
# request.on(:end) { response.end }
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# Sidenote: We could also have written
|
45
|
+
#
|
46
|
+
# def call router, request, options = {}
|
47
|
+
# # Respond to the request right away.
|
48
|
+
# response = request.respond Response.new
|
49
|
+
# # Connect the incoming stream with the outgoing stream.
|
50
|
+
# request.pipe response
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# A bit more complex example that shows the entire spec
|
54
|
+
# is a layer does nothing but two-way forwarding (short with piping).
|
55
|
+
#
|
56
|
+
# def call router, request, options = {}
|
57
|
+
# # Forward the request to the next layer.
|
58
|
+
# proxy_request = router.call request.http do |response, status|
|
59
|
+
# proxy_response = request.respond response.http, status
|
60
|
+
# response.pipe proxy_response
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# request.pipe proxy_request
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
class Layer
|
67
|
+
|
68
|
+
# Internal: Base class for Request and Response.
|
69
|
+
# Includes some modules by default.
|
70
|
+
class Communication
|
71
|
+
include EventEmitter
|
72
|
+
include Stream
|
73
|
+
|
74
|
+
attr_reader :http
|
75
|
+
|
76
|
+
# Internal: Creates a new Request/Response.
|
77
|
+
#
|
78
|
+
# http - Underlaying http Request/Response.
|
79
|
+
#
|
80
|
+
def initialize http
|
81
|
+
super()
|
82
|
+
@http = http
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Public: An inter-Layer Request.
|
87
|
+
#
|
88
|
+
# Includes EventEmitter to listen for responses, data and request end.
|
89
|
+
# Includes Stream for stream-uploading.
|
90
|
+
#
|
91
|
+
class Request < Communication
|
92
|
+
|
93
|
+
# Public: Respond to a Request using a Http Response.
|
94
|
+
# The http response the gets wrapped in a Layer Response.
|
95
|
+
#
|
96
|
+
# http - Http Response for this Request.
|
97
|
+
# status - Any status indications for the Response.
|
98
|
+
#
|
99
|
+
# Yields the Layer response and ends the response thereafter
|
100
|
+
# if a block is given.
|
101
|
+
#
|
102
|
+
# Returns the Layer Response.
|
103
|
+
def respond http, status, &lifecycle
|
104
|
+
Response.new(http).tap do |response|
|
105
|
+
emit :response, response, status
|
106
|
+
if block_given?
|
107
|
+
lifecycle.call response
|
108
|
+
response.end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Public: Returns a responder for this request.
|
114
|
+
#
|
115
|
+
# A Responder will automatically handle a response
|
116
|
+
# from a layer and use it to respond to this request.
|
117
|
+
#
|
118
|
+
# It will pipe all data from the response to the response
|
119
|
+
# for this request.
|
120
|
+
#
|
121
|
+
# Returns a block that responds to this request.
|
122
|
+
def responder
|
123
|
+
proc do |response, status|
|
124
|
+
response.pipe self.respond(response.http, status)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Public: An inter-Layer Response.
|
130
|
+
#
|
131
|
+
# Includes EventEmitter to listen for data and response end.
|
132
|
+
# Includes Stream for downloading data in chunks.
|
133
|
+
#
|
134
|
+
class Response < Communication
|
135
|
+
end
|
136
|
+
|
137
|
+
# Internal: Name of the Layer.
|
138
|
+
attr_reader :name
|
139
|
+
|
140
|
+
# Internal: Creates a new Layer.
|
141
|
+
#
|
142
|
+
# callable - Object with Layer logics that responds to #call.
|
143
|
+
# name - Name of the Layer (optional).
|
144
|
+
#
|
145
|
+
def initialize callable, name = nil
|
146
|
+
@name = name \
|
147
|
+
|| callable.class.instance_variable_get(:@name) \
|
148
|
+
|| (callable.respond_to?(:name) && callable.name)
|
149
|
+
@callable = callable
|
150
|
+
end
|
151
|
+
|
152
|
+
# Internal: Call the Layer with options fetched out of the context
|
153
|
+
# using the name of the Layer.
|
154
|
+
#
|
155
|
+
# For example, when you add a Layer to a sequence and name it auth.
|
156
|
+
# And when you then call `with auth: { key: 'secret'}` on your
|
157
|
+
# builder, `key: 'secret' will be passed as options to the Layer.
|
158
|
+
#
|
159
|
+
# router - Path of connected Layers.
|
160
|
+
# request - Request issued for this Layer.
|
161
|
+
#
|
162
|
+
# Returns Nothing
|
163
|
+
def call router, request, options = {}
|
164
|
+
@callable.call router, request, request.http.context[@name]
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
# Internal: Checks if this Layer has to be called in a certain context.
|
169
|
+
#
|
170
|
+
# context - The context the Layer is called in.
|
171
|
+
#
|
172
|
+
# Returns true if the Layer has to be called.
|
173
|
+
def callable? context
|
174
|
+
!@callable.nil? && context.enabled?(name)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Internal: Two layers are equal if there callables are equal.
|
178
|
+
def == layer
|
179
|
+
self.callable == layer.callable
|
180
|
+
end
|
181
|
+
|
182
|
+
protected
|
183
|
+
|
184
|
+
# Internal: The #call object where the logic of this Layer resides.
|
185
|
+
attr_reader :callable
|
186
|
+
end
|
187
|
+
end
|