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