Module: Syro::Deck::API

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

Instance Method Summary collapse

Instance Method Details

#call(env, inbox) ⇒ Object



263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/syro.rb', line 263

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
    instance_eval(&@syro_code)
    finish!
  end
end

#capture(arg) ⇒ Object



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

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

#consume(arg) ⇒ Object



357
358
359
# File 'lib/syro.rb', line 357

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

#defaultObject



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

def default
  yield; finish!
end

#default_headersObject



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

def default_headers
  {}
end

#deleteObject



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

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

#envObject



217
218
219
# File 'lib/syro.rb', line 217

def env
  @syro_env
end

#finish!Object



352
353
354
355
# File 'lib/syro.rb', line 352

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

#getObject



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

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)


295
296
297
# File 'lib/syro.rb', line 295

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.



348
349
350
# File 'lib/syro.rb', line 348

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

#headObject



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

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

#inboxObject



247
248
249
# File 'lib/syro.rb', line 247

def inbox
  @syro_inbox
end

#initialize(code) ⇒ Object



213
214
215
# File 'lib/syro.rb', line 213

def initialize(code)
  @syro_code = code
end

#match(arg) ⇒ Object



369
370
371
372
373
374
375
376
# File 'lib/syro.rb', line 369

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



382
383
384
# File 'lib/syro.rb', line 382

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

#optionsObject



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

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

#patchObject



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

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

#pathObject



243
244
245
# File 'lib/syro.rb', line 243

def path
  @syro_path
end

#postObject



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

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

#putObject



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

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"


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

def req
  @syro_req
end

#request_classObject



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

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>")


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

def res
  @syro_res
end

#response_classObject



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

def response_class
  Syro::Response
end

#rootObject



386
387
388
# File 'lib/syro.rb', line 386

def root
  default { yield } if root?
end

#root?Boolean

Returns:

  • (Boolean)


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

def root?
  @syro_path.root?
end

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



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

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] = @syro_path.prev
  env[Syro::INBOX] = inbox

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