commute 0.2.0.rc.2 → 0.3.0.pre
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.
- 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
|