rack-multiplexer 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6995959f7734df487ab98f351f5714867fa8159
4
- data.tar.gz: 5da14e65a19d2f3e8df203bcb05c70920b00ccdf
3
+ metadata.gz: 910894805740fdcc2364efa17ac0c7eb3a42fc4c
4
+ data.tar.gz: 99d0b9def7d71bf7972f4b1e5c5efc7c09ef9ab4
5
5
  SHA512:
6
- metadata.gz: 7a8f890c52663e8d5b908d0f47bc85392e2d3429faadbccfa14cd0f2b41ae7d4badc7585e20b915e0152b8bcaab907d6258020190f385ee758917c8a1458f297
7
- data.tar.gz: b3f3a4fac56c8dab21869a8a5e35417745c9f795cf85df192eb1ff8a6b6fa2b5d08cea449856bb08344a2665dff4e84f0626c011eb755db63b36b2872a3d32a3
6
+ metadata.gz: af73e022c78eb88ff1a48a5d5cbcbc784e781de813cc4388f27b4e4f8788d6186cc2e64f698a053c13a895267339fc752aed0f572187a47d63bafe025a043742
7
+ data.tar.gz: b5a14ed598693b692a224718cd02b7d2911b7d309f41c710a4a2ce72f50fa1c04dacb236e245ba678d69f158ccbc4b879000ba6fb9bf1f2d59515ce65db715ac
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Rack::Multiplexer
2
- Provides a simple router & dispatcher for Rack applications.
2
+ Provides a simple router & dispatcher for Rack applications as a Rack application.
3
+ The routing process takes O(1) complexity because all routes are compiled as one Regexp.
3
4
 
4
5
  ## Installation
5
6
  ```
@@ -16,10 +17,8 @@ require "rack-multiplexer"
16
17
  multiplexer = Rack::Multiplexer.new
17
18
  multiplexer.get("/a", ->(env) { [200, {}, ["a"]] })
18
19
  multiplexer.get("/b", ->(env) { [200, {}, ["b"]] })
19
- multiplexer.post("/c", ->(env) { [200, {}, ["c"]] })
20
- multiplexer.put("/d", ->(env) { [200, {}, ["c"]] })
21
- multiplexer.delete("/e", ->(env) { [200, {}, ["c"]] })
22
- multiplexer.get("/f/:g", ->(env) { [200, {}, [env["rack.request.query_hash"]["g"]]] })
20
+ multiplexer.put("/c", ->(env) { [200, {}, ["c"]] })
21
+ multiplexer.get("/d/:e", ->(env) { [200, {}, [env["rack.request.query_hash"]["e"]]] })
23
22
 
24
23
  run multiplexer
25
24
  ```
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Multiplexer
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -1,6 +1,20 @@
1
1
  require "rack/multiplexer/version"
2
2
  require "rack/request"
3
3
 
4
+ # Provides a simple router & dispatcher for Rack applications as a Rack application.
5
+ # From Ruby's standpoint, the routing algorithm has only O(1) time complexity
6
+ # because all routes are compiled as one Regexp.
7
+ #
8
+ # Example:
9
+ #
10
+ # # config.ru
11
+ # multiplexer = Rack::Multiplexer.new
12
+ # multiplexer.get("/a", ->(env) { [200, {}, ["a"]] })
13
+ # multiplexer.get("/b", ->(env) { [200, {}, ["b"]] })
14
+ # multiplexer.put("/c", ->(env) { [200, {}, ["c"]] })
15
+ # multiplexer.get("/d/:e", ->(env) { [200, {}, [env["rack.request.query_hash"]["e"]]] })
16
+ # run multiplexer
17
+ #
4
18
  module Rack
5
19
  class Multiplexer
6
20
  DEFAULT_NOT_FOUND_APPLICATION = ->(env) {
@@ -22,8 +36,8 @@ module Rack
22
36
  def call(env)
23
37
  path = env["PATH_INFO"]
24
38
  (
25
- routes[env["REQUEST_METHOD"]].find {|route| route.match?(path) } ||
26
- routes["ANY"].find {|route| route.match?(path) } ||
39
+ routes[env["REQUEST_METHOD"]].find(path) ||
40
+ routes["ANY"].find(path) ||
27
41
  @not_found_application
28
42
  ).call(env)
29
43
  end
@@ -52,9 +66,8 @@ module Rack
52
66
  routes[method] << Route.new(pattern, application)
53
67
  end
54
68
 
55
- # @routes are indexed by method.
56
69
  def routes
57
- @routes ||= Hash.new {|hash, key| hash[key] = [] }
70
+ @routes ||= Hash.new {|hash, key| hash[key] = Routes.new }
58
71
  end
59
72
 
60
73
  def default_not_found_application
@@ -70,9 +83,38 @@ module Rack
70
83
  }
71
84
  end
72
85
 
86
+ class Routes
87
+ def initialize
88
+ @routes = []
89
+ end
90
+
91
+ def find(path)
92
+ if regexp === path
93
+ @routes.size.times do |i|
94
+ return @routes[i] if Regexp.last_match("_#{i}")
95
+ end
96
+ end
97
+ end
98
+
99
+ def <<(route)
100
+ @routes << route
101
+ end
102
+
103
+ private
104
+
105
+ def regexp
106
+ @regexp ||= begin
107
+ regexps = @routes.map.with_index {|route, index| /(?<_#{index}>#{route.regexp})/ }
108
+ /\A#{Regexp.union(regexps)}\z/
109
+ end
110
+ end
111
+ end
112
+
73
113
  class Route
74
114
  PLACEHOLDER_REGEXP = /:(\w+)/
75
115
 
116
+ attr_reader :regexp
117
+
76
118
  def initialize(pattern, application)
77
119
  @application = application
78
120
  @regexp, @keys = compile(pattern)
@@ -98,7 +140,7 @@ module Rack
98
140
  keys << key
99
141
  end
100
142
  end
101
- return Regexp.new("\\A#{segments.join(?/)}\\z"), keys
143
+ return Regexp.new(segments.join(?/)), keys
102
144
  end
103
145
  end
104
146
  end
@@ -74,6 +74,7 @@ describe Rack::Multiplexer do
74
74
  it "delegates with rack.request.query_hash" do
75
75
  multiplexer = described_class.new
76
76
  multiplexer.get("/:any", application)
77
+ multiplexer.get("/a", application)
77
78
  multiplexer.call(env.merge("REQUEST_METHOD" => "GET", "PATH_INFO" => "/a"))[2][0].should == "/a?any=a&"
78
79
  end
79
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-multiplexer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-19 00:00:00.000000000 Z
11
+ date: 2013-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack