Module: Syro::Deck::API

Included in:
Syro::Deck
Defined in:
lib/syro.rb

Instance Method Summary collapse

Instance Method Details

#call(env, inbox) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/syro.rb', line 275

def call(env, inbox)
  @syro_env = env
  @syro_req = request_class.new(env)
  @syro_res = response_class.new(default_headers)
  @syro_path = Seg.new(env.fetch(Rack::PATH_INFO))
  @syro_inbox = inbox

  catch(:halt) do
    dispatch!
    finish!
  end
end

#capture(arg) ⇒ Object



373
374
375
# File 'lib/syro.rb', line 373

def capture(arg)
  @syro_path.capture(arg, inbox)
end

#consume(arg) ⇒ Object



369
370
371
# File 'lib/syro.rb', line 369

def consume(arg)
  @syro_path.consume(arg)
end

#defaultObject



390
391
392
# File 'lib/syro.rb', line 390

def default
  yield; finish!
end

#default_headersObject



263
264
265
# File 'lib/syro.rb', line 263

def default_headers
  {}
end

#deleteObject



422
423
424
# File 'lib/syro.rb', line 422

def delete
  root { res.status = 200; yield } if req.delete?
end

#envObject



229
230
231
# File 'lib/syro.rb', line 229

def env
  @syro_env
end

#finish!Object



364
365
366
367
# File 'lib/syro.rb', line 364

def finish!
  inbox[res.status]&.call
  halt(res.finish)
end

#getObject



402
403
404
# File 'lib/syro.rb', line 402

def get
  root { res.status = 200; yield } if req.get?
end

#halt(response) ⇒ Object

Immediately stops the request and returns response as per Rack’s specification.

halt([200, { "Content-Type" => "text/html" }, ["hello"]])
halt([res.status, res.headers, res.body])
halt(res.finish)


307
308
309
# File 'lib/syro.rb', line 307

def halt(response)
  throw(:halt, response)
end

#handle(status, &block) ⇒ Object

Install a handler for a given status code. Once a handler is installed, it will be called by Syro before halting the request.

handle 404 do
  res.text "Not found!"
end

If a new handler is installed for the same status code, the previous handler is overwritten. A handler is valid in the current scope and in all its nested branches. Blocks that end before the handler is installed are not affected.

For example:

on "foo" do
  # Not found
end

handle 404 do
  res.text "Not found!"
end

on "bar" do
  # Not found
end

on "baz" do
  # Not found

  handle 404 do
    res.text "Couldn't find baz"
  end
end

A request to “/foo” will return a 404, because the request method was not matched. But as the ‘on “foo”` block ends before the handler is installed, the result will be a blank screen. On the other hand, a request to “/bar” will return a 404 with the plain text “Not found!”.

Finally, a request to “/baz” will return a 404 with the plain text “Couldn’t find baz”, because by the time the ‘on “baz”` block ends a new handler is installed, and thus the previous one is overwritten.

Any status code can be handled this way, even status 200. In that case the handler will behave as a filter to be run after each successful request.



360
361
362
# File 'lib/syro.rb', line 360

def handle(status, &block)
  inbox[status] = block
end

#headObject



410
411
412
# File 'lib/syro.rb', line 410

def head
  root { res.status = 200; yield } if req.head?
end

#inboxObject



259
260
261
# File 'lib/syro.rb', line 259

def inbox
  @syro_inbox
end

#match(arg) ⇒ Object



381
382
383
384
385
386
387
388
# File 'lib/syro.rb', line 381

def match(arg)
  case arg
  when String then consume(arg)
  when Symbol then capture(arg)
  when true   then true
  else false
  end
end

#on(arg) ⇒ Object



394
395
396
# File 'lib/syro.rb', line 394

def on(arg)
  default { yield } if match(arg)
end

#optionsObject



426
427
428
# File 'lib/syro.rb', line 426

def options
  root { res.status = 200; yield } if req.options?
end

#patchObject



418
419
420
# File 'lib/syro.rb', line 418

def patch
  root { res.status = 200; yield } if req.patch?
end

#pathObject



255
256
257
# File 'lib/syro.rb', line 255

def path
  @syro_path
end

#postObject



414
415
416
# File 'lib/syro.rb', line 414

def post
  root { res.status = 200; yield } if req.post?
end

#putObject



406
407
408
# File 'lib/syro.rb', line 406

def put
  root { res.status = 200; yield } if req.put?
end

#reqObject

Returns the incoming request object. This object is an instance of Rack::Request.

req.post?      # => true
req.params     # => { "username" => "bob", "password" => "secret" }
req[:username] # => "bob"


240
241
242
# File 'lib/syro.rb', line 240

def req
  @syro_req
end

#request_classObject



267
268
269
# File 'lib/syro.rb', line 267

def request_class
  Rack::Request
end

#resObject

Returns the current response object. This object is an instance of Syro::Response.

res.status = 200
res["Content-Type"] = "text/html"
res.write("<h1>Welcome back!</h1>")


251
252
253
# File 'lib/syro.rb', line 251

def res
  @syro_res
end

#response_classObject



271
272
273
# File 'lib/syro.rb', line 271

def response_class
  Syro::Response
end

#rootObject



398
399
400
# File 'lib/syro.rb', line 398

def root
  default { yield } if root?
end

#root?Boolean

Returns:

  • (Boolean)


377
378
379
# File 'lib/syro.rb', line 377

def root?
  @syro_path.root?
end

#run(app, inbox = {}) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
# File 'lib/syro.rb', line 288

def run(app, inbox = {})
  path, script = env[Rack::PATH_INFO], env[Rack::SCRIPT_NAME]

  env[Rack::PATH_INFO] = @syro_path.curr
  env[Rack::SCRIPT_NAME] = script.to_s + @syro_path.prev
  env[Syro::INBOX] = inbox

  halt(app.call(env))
ensure
  env[Rack::PATH_INFO], env[Rack::SCRIPT_NAME] = path, script
end