Class: RackDispatch::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/rack_dispatch/application.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.as(role) ⇒ Object



3
4
5
# File 'lib/rack_dispatch/application.rb', line 3

def self.as(role)
  _previous_role = @role ; @role = role ; yield ; @role = _previous_role
end

.route(method, path, with: {}, thereupon: nil, redirect: nil, template: nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rack_dispatch/application.rb', line 7

def self.route(method, path, with: {}, thereupon: nil, redirect: nil, template: nil)
  builders = []
  handlers = {}

  pattern_scan = path.scan(/(\:([a-z_]+))/).flatten.map do |value|
  if value.match(':')
    value
  else
    builder_class = Object.const_get("#{value}_builder".split('_').map(&:capitalize).join)
    builders << builder_class.new
    builder_class.regexp
  end
  end

  pattern_keys = pattern_scan.select.with_index { |_, i| i.even? }
  pattern = /\A#{path.gsub(Regexp.union(pattern_keys), Hash[*pattern_scan])}\z/

  with.each do |handler_name, condition|
  handler = Object.const_get("#{handler_name}_handler".split('_').map(&:capitalize).join).new
  handlers[handler] = condition
  end

  tasks = Array(thereupon).map do |task_name|
  Object.const_get("#{task_name}_task".split('_').map(&:capitalize).join).new
  end

  destination = template ? TemplateDestination.new(template) : RedirectDestination.new(redirect)

  ((@routes ||= {})[method.to_s.downcase] ||= []) << [pattern, builders, handlers, tasks, destination]
end

Instance Method Details

#call(env) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rack_dispatch/application.rb', line 38

def call(env)
  request = Rack::Request.new(env)
  response = Rack::Response.new
  computed_handlers = {}

  routes = self.class.instance_variable_get(:@routes)[request.request_method.downcase].select do |pattern, builders, handlers, tasks, destination|
  pattern.match(request.path) do |matches|
    # user matching

    builders.zip(matches[1..-1]).all? do |builder, value|
 builder_name = builder.class.name.sub(/Builder\z/, '').gsub(/(.)([A-Z])/,'\1_\2').downcase

 if request.params[builder_name]
   true
 elsif result = builder.call(value)
   request.update_param(builder_name, result) ; true
 end
    end
  end
  end

  route = routes.find do |pattern, builders, handlers, tasks, destination|
  handlers.all? do |handler, condition|
    (computed_handlers.key?(handler) && computed_handlers[handler] == condition) ||
 ((computed_handlers[handler] = handler.call(request)) == condition)
  end
  end

  if route
  route[3].each do |task|
    task.call(response)
  end

  route.last.call(request, response)
  else
  response.status = 404
  response.write 'Not Found'
  end

  response.finish
end