rack_dispatch 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15e33270181787eb3d17cea8b09e04c5a88af3c0
4
- data.tar.gz: 1db328a2ce599bf593509acff02f55ed11a6461e
3
+ metadata.gz: 31fa12b35c055e0baf7ec860d3b182ab13d212c5
4
+ data.tar.gz: 9156c852f833047b140ac948cf12e6ccaeeb01a7
5
5
  SHA512:
6
- metadata.gz: 77f8e79cd8582be4a2c76755176432e3ad6d1acd33eafddd5af6b7b52480883e05ca68f795bf50996d0a236c5601dad5305677309085287c95408f7e6f29ba50
7
- data.tar.gz: 8de067fec021d7dfd9d22b541c431bb8476201f4ed108d172cb9af43d4c3330c924b8362b13c34912ed9eb18c1142b7d7c69c28ef07d287214ab5a52782f7fbe
6
+ metadata.gz: e30572451eea34e3766f7771cb7f28f67295883232cdab4f97048faf6c6c20d0bb54eb570b6713005bbb956d721b3070b28bfeda80419dcdc7d9bb738de2fb52
7
+ data.tar.gz: 5efd2bcd376e8ae5c82a8032b06f101e76f873d437fda8a2ccabb374ff0459574636595e0dc335e241fb940931e7fbcbe77345ec3cd4e38393c4ed5ca1698a13
data/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # RackDispatch
2
2
 
3
- A simple toolkit for building Ruby web application with Rack.
3
+ A simple toolkit for building Ruby web applications with Rack.
@@ -1,5 +1,6 @@
1
+ require 'liquid'
1
2
  require 'rack'
2
- require 'rack_dispatch/application'
3
- require 'rack_dispatch/redirect_handler'
4
- require 'rack_dispatch/template_handler'
5
- require 'rack_dispatch/version'
3
+ require_relative 'rack_dispatch/application'
4
+ require_relative 'rack_dispatch/redirect_destination'
5
+ require_relative 'rack_dispatch/template_destination'
6
+ require_relative 'rack_dispatch/version'
@@ -1,44 +1,80 @@
1
1
  module RackDispatch
2
2
  class Application
3
- class << self
4
- %i[get post put patch delete head options].each do |http_method|
5
- define_method(http_method) do |*args|
6
- match(http_method, *args)
3
+ def self.as(role)
4
+ _previous_role = @role ; @role = role ; yield ; @role = _previous_role
5
+ end
6
+
7
+ def self.route(method, path, with: {}, thereupon: nil, redirect: nil, template: nil)
8
+ builders = []
9
+ handlers = {}
10
+
11
+ pattern_scan = path.scan(/(\:([a-z_]+))/).flatten.map do |value|
12
+ if value.match(':')
13
+ value
14
+ else
15
+ builder_class = Object.const_get("#{value}_builder".split('_').map(&:capitalize).join)
16
+ builders << builder_class.new
17
+ builder_class.regexp
7
18
  end
8
19
  end
9
20
 
10
- def default(options = {})
11
- @default_handler = handler(options)
21
+ pattern_keys = pattern_scan.select.with_index { |_, i| i.even? }
22
+ pattern = /\A#{path.gsub(Regexp.union(pattern_keys), Hash[*pattern_scan])}\z/
23
+
24
+ with.each do |handler_name, condition|
25
+ handler = Object.const_get("#{handler_name}_handler".split('_').map(&:capitalize).join).new
26
+ handlers[handler] = condition
12
27
  end
28
+
29
+ tasks = Array(thereupon).map do |task_name|
30
+ Object.const_get("#{task_name}_task".split('_').map(&:capitalize).join).new
31
+ end
32
+
33
+ destination = template ? TemplateDestination.new(template) : RedirectDestination.new(redirect)
34
+
35
+ ((@routes ||= {})[method.to_s.downcase] ||= []) << [pattern, builders, handlers, tasks, destination]
13
36
  end
14
37
 
15
38
  def call(env)
16
- route(Rack::Request.new(env))
17
- end
39
+ request = Rack::Request.new(env)
40
+ response = Rack::Response.new
41
+ computed_handlers = {}
18
42
 
19
- private
43
+ routes = self.class.instance_variable_get(:@routes)[request.request_method.downcase].select do |pattern, builders, handlers, tasks, destination|
44
+ pattern.match(request.path) do |matches|
45
+ # user matching
20
46
 
21
- def self.match(method, path, options = {})
22
- ((@routes ||= {})[[String(method), String(path)]] ||= []) << [options.delete(:with), handler(options)]
23
- end
47
+ builders.zip(matches[1..-1]).all? do |builder, value|
48
+ builder_name = builder.class.name.sub(/Builder\z/, '').gsub(/(.)([A-Z])/,'\1_\2').downcase
24
49
 
25
- def self.handler(options = {})
26
- redirect, template, to = options.delete(:redirect), options.delete(:template), options.delete(:to)
27
- raise ArgumentError, 'must provide :template, :redirect or :to option' unless [redirect, template, to].compact.one?
50
+ if request.params[builder_name]
51
+ true
52
+ elsif result = builder.call(value)
53
+ request.update_param(builder_name, result) ; true
54
+ end
55
+ end
56
+ end
57
+ end
28
58
 
29
- if redirect
30
- RedirectHandler.new(redirect, options)
31
- elsif template
32
- TemplateHandler.new(template, options)
59
+ route = routes.find do |pattern, builders, handlers, tasks, destination|
60
+ handlers.all? do |handler, condition|
61
+ (computed_handlers.key?(handler) && computed_handlers[handler] == condition) ||
62
+ ((computed_handlers[handler] = handler.call(request)) == condition)
63
+ end
64
+ end
65
+
66
+ if route
67
+ route[3].each do |task|
68
+ task.call(response)
69
+ end
70
+
71
+ route.last.call(request, response)
33
72
  else
34
- to
73
+ response.status = 404
74
+ response.write 'Not Found'
35
75
  end
36
- end
37
76
 
38
- def route(request)
39
- self.class.instance_variable_get(:@routes)&.[]([request.request_method.downcase, request.path]).find do |constraint, _|
40
- constraint.nil? || constraint.call(*constraint.parameters.map(&:last).map { |key| request.params[key.to_s] })
41
- end&.last&.call or self.class.instance_variable_get(:@default_handler)&.call
77
+ response.finish
42
78
  end
43
79
  end
44
80
  end
@@ -0,0 +1,12 @@
1
+ module RackDispatch
2
+ class RedirectDestination
3
+ def initialize(path, status: 302)
4
+ @path = path
5
+ @status = status
6
+ end
7
+
8
+ def call(request, response)
9
+ response.redirect(@path, @status)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module RackDispatch
2
+ class TemplateDestination
3
+ def initialize(path)
4
+ @path = File.expand_path(File.join('templates', String(path)), Dir.pwd) + '.liquid'
5
+ end
6
+
7
+ def call(request, response)
8
+ response['Content-Type'] = 'text/html'
9
+ response.write(render(request.params))
10
+ end
11
+
12
+ def render(data = {})
13
+ Liquid::Template.parse(File.read(@path)).render(data)
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module RackDispatch
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack_dispatch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theodore Kimble
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: liquid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rack
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,8 +53,8 @@ files:
39
53
  - README.md
40
54
  - lib/rack_dispatch.rb
41
55
  - lib/rack_dispatch/application.rb
42
- - lib/rack_dispatch/redirect_handler.rb
43
- - lib/rack_dispatch/template_handler.rb
56
+ - lib/rack_dispatch/redirect_destination.rb
57
+ - lib/rack_dispatch/template_destination.rb
44
58
  - lib/rack_dispatch/version.rb
45
59
  homepage: https://github.com/theodorekimble/rack_dispatch
46
60
  licenses:
@@ -65,5 +79,5 @@ rubyforge_project:
65
79
  rubygems_version: 2.5.1
66
80
  signing_key:
67
81
  specification_version: 4
68
- summary: A simple toolkit for building Ruby web application with Rack
82
+ summary: A simple toolkit for building Ruby web applications with Rack
69
83
  test_files: []
@@ -1,19 +0,0 @@
1
- module RackDispatch
2
- class RedirectHandler
3
- def initialize(path, status: 302)
4
- @path = path
5
- @status = status
6
- end
7
-
8
- def call
9
- [
10
- @status,
11
- {
12
- 'Content-Type' => 'text/html',
13
- 'Location' => @path,
14
- },
15
- ["Redirect to <a href=\"#@path\">#@path</a>"],
16
- ]
17
- end
18
- end
19
- end
@@ -1,28 +0,0 @@
1
- module RackDispatch
2
- class TemplateHandler
3
- def initialize(path, status: 200, content_type: 'text/html', error: nil)
4
- @path = File.expand_path(File.join('templates', path), Dir.pwd)
5
- @status = Integer(status)
6
- @content_type = String(content_type)
7
- @error = error
8
- end
9
-
10
- def call
11
- [
12
- @status,
13
- {
14
- 'Content-Type' => @content_type,
15
- },
16
- [ERB.new(File.read(@path)).result(OpenStruct.new(template_variables).instance_eval { binding })],
17
- ]
18
- end
19
-
20
- private
21
-
22
- def template_variables
23
- {
24
- error: @error,
25
- }
26
- end
27
- end
28
- end