rack-app 5.11.0 → 5.11.1

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: 070c847ed07e3494ed51e88ebf084c6eb661a30f
4
- data.tar.gz: 4b836fb0a7d4c38491b4d2774b85289d528c1c56
3
+ metadata.gz: 4d2a02f6b4e7653fa9647f92c3aff43878fd64c2
4
+ data.tar.gz: e262d7601e24a4f451ffa43dcabfd1ca0bab0220
5
5
  SHA512:
6
- metadata.gz: 566de7abd739139b8ac5980bcad9079995892d36c1f7213cadedd2451d62ce6ee7f41a2c23327c7174e0576b20ab1b7d71cbfab0b01a79424bb77ae63e35ade3
7
- data.tar.gz: 91ac3f3615722f31dc483aa4cd4845902d8270655cb1a2e96c2fa72d78add151692ed0cc5a6304c6a5ad6f10a06d40e66c589ceb604b188b944d0fda8d18fb38
6
+ metadata.gz: bb38fe1f45db780873148bdf662baa41bc0cf84762204aa3be46ee8ffaa7495b6bfa707dc8a93069ee3f6509271bed3f70734491c331fa9cee5348544a12403c
7
+ data.tar.gz: 3177c3c9643288694a0d8ec3f51ec644cf5e9ee3a9e787e8169952b850e97df51af114dd20f3b02056fa059c02eb6bb1ca9f30d192882835febda8147eb85539
data/README.md CHANGED
@@ -68,10 +68,10 @@ Yes, in fact it's already powering heroku hosted micro-services.
68
68
  * syntax sugar for default header definitions
69
69
  * namespaces for endpoint request path declarations so it can be dry and unified
70
70
  * no Class method bloat, so you can enjoy pure ruby without any surprises
71
- * App mounting so you can crete separated controllers for different task
71
+ * App mounting so you can crete separated controllers for different task
72
72
  * Streaming
73
- * Null time look up routing
74
- * allows as many endpoint registration to you as you want, without impact on route look up speed
73
+ * O(log(n)) lookup routing
74
+ * allows as many endpoint registration to you as you want, without impact on route lookup speed
75
75
  * only basic sets for instance method lvl for the must need tools, such as params, payload
76
76
  * simple to use class level response serializer
77
77
  * so you can choose what type of serialization you want without any enforced convention
@@ -100,7 +100,7 @@ Yes, in fact it's already powering heroku hosted micro-services.
100
100
 
101
101
  * **[David Bush](https://github.com/disavowd)**
102
102
 
103
- * [wrote an article](https://www.sitepoint.com/rack-app-a-performant-and-pragmatic-web-microframework/) about the project
103
+ * [wrote an awesome article](https://www.sitepoint.com/rack-app-a-performant-and-pragmatic-web-microframework/) about the project
104
104
 
105
105
  ## [Contributing](CONTRIBUTING.md)
106
106
 
@@ -133,7 +133,7 @@ require 'rack/app'
133
133
 
134
134
  class App < Rack::App
135
135
 
136
- apply_extensions :front_end
136
+ apply_extensions :front_end
137
137
 
138
138
  mount SomeAppClass
139
139
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.11.0
1
+ 5.11.1
@@ -54,11 +54,14 @@ module Rack::App::Constants
54
54
  PATH_PARAMS = 'rack-app.path_params'.freeze
55
55
  ORIGINAL_PATH_INFO = 'rack-app.original_path_info'.freeze
56
56
  FORMATTED_PATH_INFO = 'rack-app.formatted_path_info'.freeze
57
+ SPLITTED_PATH_INFO = 'rack-app.splitted_path_info'.freeze
57
58
  METHODOVERRIDE_ORIGINAL_METHOD = 'rack-app.methodoverride.original_method'.freeze
58
59
 
59
60
  end
60
61
 
61
- MOUNTED_DIRECTORY = '[Mounted Directory]'.freeze
62
- RACK_BASED_APPLICATION = '[Mounted Rack Application]'.freeze
62
+ module PATH
63
+ MOUNT_POINT = "[MOUNT_POINT]".freeze
64
+ APPLICATION = "[Mounted Application]".freeze
65
+ end
63
66
 
64
67
  end
@@ -0,0 +1,35 @@
1
+ class Rack::App::Middlewares::SetPathParams
2
+
3
+ def initialize(app, params_lookup_hash)
4
+ @params_lookup_hash = params_lookup_hash
5
+ @app = app
6
+ end
7
+
8
+ E = Rack::App::Constants::ENV
9
+
10
+ def call(env)
11
+ populate_path_params(env)
12
+ correct_last_value_from_extensions(env)
13
+ @app.call(env)
14
+ end
15
+
16
+ protected
17
+
18
+ def populate_path_params(env)
19
+ @params_lookup_hash.each do |index, key|
20
+ env[E::PATH_PARAMS][key] = env[E::SPLITTED_PATH_INFO][index]
21
+ end
22
+ end
23
+
24
+ def correct_last_value_from_extensions(env)
25
+ last_index = env[E::SPLITTED_PATH_INFO].length - 1
26
+ return if @params_lookup_hash[last_index].nil?
27
+ extless(env[E::PATH_PARAMS][@params_lookup_hash[last_index]])
28
+ end
29
+
30
+ def extless(value)
31
+ extname = File.extname(value)
32
+ value.slice!(/#{Regexp.escape(extname)}$/) unless extname.empty?
33
+ end
34
+
35
+ end
@@ -1,5 +1,6 @@
1
1
  module Rack::App::Middlewares
2
2
  require 'rack/app/middlewares/path_info_cutter'
3
+ require 'rack/app/middlewares/set_path_params'
3
4
  require 'rack/app/middlewares/configuration'
4
5
  require 'rack/app/middlewares/header_setter'
5
6
  require 'rack/app/middlewares/payload'
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ class Rack::App::Router::Tree::Branch < ::Hash
3
+
4
+ def set(env)
5
+ if env.branch?
6
+ branch_for(env.save_key).set(env.next)
7
+ else
8
+ leaf.set(env)
9
+ end
10
+ end
11
+
12
+ def call(env, current, *path_info_parts)
13
+ if path_info_parts.empty?
14
+ try_leaf { |l| l.call_endpoint(env, current) || l.call_mount(env) }
15
+ else
16
+ next_branch = self[current] || self[:ANY]
17
+ resp = next_branch && next_branch.call(env, *path_info_parts)
18
+ resp || try_leaf { |l| l.call_mount(env) }
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def try_leaf
25
+ leaf = self[:LEAF]
26
+ leaf && yield(leaf)
27
+ end
28
+
29
+ def branch_for(save_key)
30
+ self[save_key] ||= self.class.new
31
+ end
32
+
33
+ def leaf
34
+ self[:LEAF] ||= Rack::App::Router::Tree::Leaf.new
35
+ end
36
+
37
+ end
@@ -1,13 +1,67 @@
1
1
  # frozen_string_literal: true
2
- module Rack::App::Router::Tree::Env
3
- extend(self)
2
+ class Rack::App::Router::Tree::Env
4
3
 
5
- E = Rack::App::Constants::ENV
4
+ attr_reader :request_path_parts, :endpoint, :params
6
5
 
7
- def configure(env)
8
- env[E::PATH_PARAMS] ||= {}
9
- env[E::FORMATTED_PATH_INFO] = Rack::App::Utils.normalize_path(env[E::PATH_INFO])
10
- env[E::EXTNAME] = File.extname(Rack::App::Utils.split_path_info(env[E::FORMATTED_PATH_INFO]).last)
11
- env[E::FORMATTED_PATH_INFO].slice!(/#{Regexp.escape(env[E::EXTNAME])}$/)
6
+ def current
7
+ @request_path_parts[@index]
12
8
  end
9
+
10
+ def branch?
11
+ !clean_request_path_parts[@index..-2].empty?
12
+ end
13
+
14
+ def type
15
+ case @request_path_parts.last
16
+ when Rack::App::Constants::PATH::APPLICATION
17
+ :APPLICATION
18
+ when Rack::App::Constants::PATH::MOUNT_POINT
19
+ :MOUNT_POINT
20
+ else
21
+ :ENDPOINT
22
+ end
23
+ end
24
+
25
+ def save_key
26
+ if current =~ /^:\w+$/i
27
+ @params[@index]= current.sub(/^:/, '')
28
+ :ANY
29
+ else
30
+ current
31
+ end
32
+ end
33
+
34
+ def next
35
+ env = self.dup
36
+ env.inc_index!
37
+ env
38
+ end
39
+
40
+ protected
41
+
42
+ def initialize(endpoint)
43
+ @index = 0
44
+ @params = {}
45
+ @endpoint = endpoint
46
+ @request_path_parts = request_path_parts_by(endpoint).freeze
47
+ end
48
+
49
+ def request_path_parts_by(endpoint)
50
+ u = Rack::App::Utils
51
+ u.split_path_info(u.normalize_path(endpoint.request_path))
52
+ end
53
+
54
+ def inc_index!
55
+ @index += 1
56
+ end
57
+
58
+ SPECIAL_PATH_ELEMENTS = [
59
+ Rack::App::Constants::PATH::APPLICATION,
60
+ Rack::App::Constants::PATH::MOUNT_POINT
61
+ ].freeze
62
+
63
+ def clean_request_path_parts
64
+ @request_path_parts - SPECIAL_PATH_ELEMENTS
65
+ end
66
+
13
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- class Rack::App::Router::Tree::Mounted::Application < Rack::App::Router::Tree::Mounted
2
+ class Rack::App::Router::Tree::Leaf::Mounted::Application < Rack::App::Router::Tree::Leaf::Mounted
3
3
  protected
4
4
 
5
5
  def initialize(endpoint)
@@ -14,7 +14,7 @@ class Rack::App::Router::Tree::Mounted::Application < Rack::App::Router::Tree::M
14
14
  end
15
15
 
16
16
  def mount_path(endpoint)
17
- mount_path_parts = (endpoint.request_path.split('/') - [Rack::App::Constants::RACK_BASED_APPLICATION, ''])
17
+ mount_path_parts = (endpoint.request_path.split('/') - [Rack::App::Constants::PATH::APPLICATION, ''])
18
18
  mount_path_parts.empty? ? '' : Rack::App::Utils.join(mount_path_parts)
19
19
  end
20
20
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
- class Rack::App::Router::Tree::Mounted
2
+ class Rack::App::Router::Tree::Leaf::Mounted
3
3
 
4
- require 'rack/app/router/tree/mounted/application'
4
+ require 'rack/app/router/tree/leaf/mounted/application'
5
5
 
6
- def get(env)
6
+ def call(env)
7
7
  @app.call(env)
8
8
  end
9
9
 
@@ -1,34 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
  class Rack::App::Router::Tree::Leaf < ::Hash
3
- require 'rack/app/router/tree/leaf/vein'
4
3
 
5
- def get(env)
6
- vein = vein_by(env)
7
- vein && vein.get(env)
8
- end
4
+ require 'rack/app/router/tree/leaf/mounted'
5
+
6
+ E = Rack::App::Constants::ENV
9
7
 
10
- def set(endpoint)
11
- endpoint.request_methods.each do |request_method|
12
- vein_for(request_method).set(endpoint)
8
+ def set(env)
9
+ case env.type
10
+ when :APPLICATION
11
+ self[env.type] = Rack::App::Router::Tree::Leaf::Mounted::Application.new(env.endpoint)
12
+ when :MOUNT_POINT
13
+ self[env.type] = Rack::App::Router::Tree::Leaf::Mounted.new(env.endpoint)
14
+ else
15
+ save_endpoint(env)
13
16
  end
14
17
  end
15
18
 
16
- def struct
17
- hash = {}
18
- self.each do |request_method, vein|
19
- hash[request_method] = vein.struct
20
- end
21
- hash
19
+ def call_endpoint(env, current_path)
20
+ app = self[current_path] || self[:ANY]
21
+ (app && app.call(env)) || call_mount(env)
22
+ end
23
+
24
+ def call_mount(env)
25
+ app = self[:MOUNT_POINT] || self[:APPLICATION]
26
+ app && app.call(env)
22
27
  end
23
28
 
24
29
  protected
25
30
 
26
- def vein_by(env)
27
- self[env[Rack::App::Constants::ENV::REQUEST_METHOD].to_sym]
31
+ def save_endpoint(env)
32
+ if env.save_key.is_a?(Symbol)
33
+ vein_for(env.save_key).set(env)
34
+ else
35
+ split_save_to_extnames(env)
36
+ end
28
37
  end
29
38
 
30
- def vein_for(request_method)
31
- self[request_method] ||= Rack::App::Router::Tree::Leaf::Vein.new
39
+ def split_save_to_extnames(env)
40
+ save_key = env.save_key
41
+ env.endpoint.config.serializer.extnames.each do |extname|
42
+ vein_for(save_key + extname).set(env)
43
+ end
44
+ vein_for(save_key).set(env)
32
45
  end
33
46
 
47
+ def vein_for(path_part)
48
+ self[path_part] ||= Rack::App::Router::Tree::Vein.new
49
+ end
50
+
51
+
34
52
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ class Rack::App::Router::Tree::Vein < ::Hash
3
+
4
+ def set(env)
5
+ app = create_app(env)
6
+ env.endpoint.request_methods.each do |request_method|
7
+ self[request_method.to_s.upcase] = app
8
+ end
9
+ end
10
+
11
+ def call(env)
12
+ app = app_by(env)
13
+ app && app.call(env)
14
+ end
15
+
16
+ protected
17
+
18
+ def app_by(env)
19
+ self[env[Rack::App::Constants::ENV::REQUEST_METHOD]]
20
+ end
21
+
22
+ def create_app(env)
23
+ app = env.endpoint.to_app
24
+ env.params.empty? ? app : wrap(app, env.params)
25
+ end
26
+
27
+ def wrap(app, params)
28
+ builder = Rack::Builder.new
29
+ builder.use(Rack::App::Middlewares::SetPathParams, params)
30
+ builder.run(app)
31
+ builder.to_app
32
+ end
33
+
34
+ end
@@ -2,39 +2,49 @@
2
2
  class Rack::App::Router::Tree
3
3
 
4
4
  require 'rack/app/router/tree/env'
5
- require 'rack/app/router/tree/node'
5
+
6
+ require 'rack/app/router/tree/branch'
6
7
  require 'rack/app/router/tree/leaf'
7
- require 'rack/app/router/tree/mounted'
8
+ require 'rack/app/router/tree/vein'
9
+
10
+ attr_reader :root
8
11
 
9
12
  def initialize
10
- @root = self.class::Node.new
13
+ @root = self.class::Branch.new
11
14
  end
12
15
 
13
16
  def add(endpoint)
14
- @root.set(endpoint, *path_info_parts_by(endpoint.request_path))
17
+ @root.set(self.class::Env.new(endpoint))
15
18
  end
16
19
 
17
20
  def call(env)
18
- self.class::Env.configure(env)
19
- @root.get(env, *path_info_parts_by(env[Rack::App::Constants::ENV::FORMATTED_PATH_INFO]))
21
+ configure_request(env)
22
+ @root.call(env, *env[Rack::App::Constants::ENV::SPLITTED_PATH_INFO])
20
23
  end
21
24
 
22
25
  protected
23
26
 
24
- def request_methods(endpoint)
25
- case endpoint.request_method
26
- when ::Rack::App::Constants::HTTP::METHOD::ANY
27
- ::Rack::App::Constants::HTTP::METHODS.each{|m| yield(m) }
28
- else
29
- yield(endpoint.request_method)
30
- end
27
+ E = Rack::App::Constants::ENV
28
+
29
+ def configure_request(env)
30
+ env[E::PATH_PARAMS] ||= {}
31
+ fpi = format_path_info(env).freeze
32
+ env[E::FORMATTED_PATH_INFO] = fpi
33
+ spi = split_path_info(fpi).freeze
34
+ env[E::SPLITTED_PATH_INFO] = spi
35
+ env[E::EXTNAME] = extname(spi)
31
36
  end
32
37
 
33
- def cluster(request_method)
34
- @methods[request_method.to_s.upcase] ||= Rack::App::Router::Tree::Node.new
38
+ def format_path_info(env)
39
+ Rack::App::Utils.normalize_path(env[E::PATH_INFO])
35
40
  end
36
41
 
37
- def path_info_parts_by(path_info)
38
- Rack::App::Utils.split_path_info(Rack::App::Utils.normalize_path(path_info))
42
+ def split_path_info(formatted_path_info)
43
+ Rack::App::Utils.split_path_info(formatted_path_info)
39
44
  end
45
+
46
+ def extname(splitted_path_info)
47
+ File.extname(splitted_path_info.last)
48
+ end
49
+
40
50
  end
@@ -2,6 +2,8 @@ class Rack::App::Router
2
2
 
3
3
  require 'rack/app/router/tree'
4
4
 
5
+ attr_reader :tree
6
+
5
7
  NOT_FOUND_APP = lambda do |env|
6
8
  rack_response = Rack::Response.new
7
9
  rack_response.status = 404
@@ -61,7 +63,6 @@ class Rack::App::Router
61
63
 
62
64
  protected
63
65
 
64
-
65
66
  def initialize
66
67
  reset
67
68
  end
@@ -31,18 +31,14 @@ module Rack::App::SingletonMethods::Mounting
31
31
  directory_full_path = ::Rack::App::Utils.expand_path(directory_path)
32
32
 
33
33
  namespace options[:to] do
34
-
35
34
  Dir.glob(File.join(directory_full_path, '**', '*')).each do |file_path|
36
-
37
35
  request_path = file_path.sub(/^#{Regexp.escape(directory_full_path)}/, '')
38
36
  get(request_path) { serve_file(file_path) }
39
37
  options(request_path) { '' }
40
-
41
38
  end
42
-
43
39
  end
44
- nil
45
40
 
41
+ nil
46
42
  end
47
43
 
48
44
  alias create_endpoints_for_files_in mount_directory
@@ -50,7 +46,7 @@ module Rack::App::SingletonMethods::Mounting
50
46
 
51
47
  def serve_files_from(file_path, options={})
52
48
  file_server = Rack::App::FileServer.new(Rack::App::Utils.expand_path(file_path))
53
- request_path = Rack::App::Utils.join(@namespaces, options[:to], '**', '*')
49
+ request_path = Rack::App::Utils.join(@namespaces, options[:to], Rack::App::Constants::PATH::MOUNT_POINT)
54
50
 
55
51
  endpoint = Rack::App::Endpoint.new(
56
52
  route_registration_properties.merge(
@@ -74,7 +70,7 @@ module Rack::App::SingletonMethods::Mounting
74
70
  :request_path => Rack::App::Utils.join(
75
71
  @namespaces,
76
72
  options[:to],
77
- ::Rack::App::Constants::RACK_BASED_APPLICATION
73
+ Rack::App::Constants::PATH::APPLICATION
78
74
  ),
79
75
  :application => rack_based_app
80
76
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-app
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.11.0
4
+ version: 5.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Luzsi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-31 00:00:00.000000000 Z
11
+ date: 2017-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,6 +138,7 @@ files:
138
138
  - lib/rack/app/middlewares/path_info_cutter.rb
139
139
  - lib/rack/app/middlewares/payload.rb
140
140
  - lib/rack/app/middlewares/payload/parser_setter.rb
141
+ - lib/rack/app/middlewares/set_path_params.rb
141
142
  - lib/rack/app/params.rb
142
143
  - lib/rack/app/payload.rb
143
144
  - lib/rack/app/payload/builder.rb
@@ -149,12 +150,12 @@ files:
149
150
  - lib/rack/app/router.rb
150
151
  - lib/rack/app/router/base.rb
151
152
  - lib/rack/app/router/tree.rb
153
+ - lib/rack/app/router/tree/branch.rb
152
154
  - lib/rack/app/router/tree/env.rb
153
155
  - lib/rack/app/router/tree/leaf.rb
154
- - lib/rack/app/router/tree/leaf/vein.rb
155
- - lib/rack/app/router/tree/mounted.rb
156
- - lib/rack/app/router/tree/mounted/application.rb
157
- - lib/rack/app/router/tree/node.rb
156
+ - lib/rack/app/router/tree/leaf/mounted.rb
157
+ - lib/rack/app/router/tree/leaf/mounted/application.rb
158
+ - lib/rack/app/router/tree/vein.rb
158
159
  - lib/rack/app/serializer.rb
159
160
  - lib/rack/app/serializer/formats_builder.rb
160
161
  - lib/rack/app/singleton_methods.rb
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
- class Rack::App::Router::Tree::Leaf::Vein < ::Hash
3
-
4
- E = Rack::App::Constants::ENV
5
-
6
- def set(endpoint)
7
- app = endpoint.to_app
8
- endpoint.config.serializer.extnames.each do |extname|
9
- self[extname] = app
10
- end
11
- self[extname_for(endpoint)] = app
12
- end
13
-
14
- def get(env)
15
- app = self[env[E::EXTNAME]]
16
- app && app.call(env)
17
- end
18
-
19
- def struct
20
- self.reduce({}) do |hash, (extname, app)|
21
- hash[extname]= :app
22
- hash
23
- end
24
- end
25
-
26
- protected
27
-
28
- def extname_for(endpoint)
29
- File.extname(Rack::App::Utils.split_path_info(endpoint.request_path).last)
30
- end
31
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
- class Rack::App::Router::Tree::Node < ::Hash
3
-
4
- PARAM = :PARAM
5
-
6
- def set(endpoint, current=nil, *path_info_parts)
7
- case type(current)
8
- when :NODE
9
- node_for(save_key(current)).set(endpoint, *path_info_parts)
10
- when :LEAF
11
- save_to_leaf(endpoint)
12
- when :RACK_BASED_APPLICATION
13
- attach(:RACK_BASED_APPLICATION, Rack::App::Router::Tree::Mounted::Application.new(endpoint))
14
- when :MOUNTED
15
- attach(:MOUNT, Rack::App::Router::Tree::Mounted.new(endpoint))
16
- else
17
- raise('UNKNOWN')
18
- end
19
- end
20
-
21
- def get(env, current=nil, *path_info_parts)
22
- return app_for(env) if current.nil?
23
- node = next_node(env, current)
24
- (node && node.get(env, *path_info_parts)) || mounted(env)
25
- end
26
-
27
- def struct
28
- self.reduce({}) do |hash, (k,v)|
29
- if k == PARAM
30
- hash[k] = v
31
- else
32
- hash[k] = v.struct
33
- end
34
- hash
35
- end
36
- end
37
-
38
- protected
39
-
40
- def app_for(env)
41
- app = self[:LEAF] || mounted_app
42
- app && app.get(env)
43
- end
44
-
45
- def mounted(env)
46
- mounted_app && mounted_app.get(env)
47
- end
48
-
49
- def mounted_app
50
- self[:MOUNT] || self[:RACK_BASED_APPLICATION]
51
- end
52
-
53
- def attach(key, app_or_endpoint)
54
- self[key.to_sym] = app_or_endpoint
55
- end
56
-
57
- def save_to_leaf(endpoint)
58
- self[:LEAF] ||= Rack::App::Router::Tree::Leaf.new
59
- self[:LEAF].set(endpoint)
60
- end
61
-
62
- def next_node(env, current)
63
- self[current] || any_path(env, current)
64
- end
65
-
66
- def any_path(env, current)
67
- if self[:ANY]
68
- env[Rack::App::Constants::ENV::PATH_PARAMS][self[PARAM]] = current
69
- self[:ANY]
70
- end
71
- end
72
-
73
- def node_for(key)
74
- self[key] ||= self.class.new
75
- end
76
-
77
- def type(current)
78
- case current
79
- when Rack::App::Constants::RACK_BASED_APPLICATION
80
- :RACK_BASED_APPLICATION
81
- when '**','*'
82
- :MOUNTED
83
- when NilClass
84
- :LEAF
85
- else
86
- :NODE
87
- end
88
- end
89
-
90
- def save_key(path)
91
- case path
92
- when /^:\w+$/i
93
- self[PARAM] = path.sub(/^:/, '')
94
- :ANY
95
- else
96
- extnameless(path)
97
- end
98
- end
99
-
100
- def extnameless(path)
101
- path.sub(/\.\w+$/,'')
102
- end
103
-
104
- end