lib/usher/node.rb in joshbuddy-usher-0.5.1 vs lib/usher/node.rb in joshbuddy-usher-0.5.2
- old
+ new
@@ -2,11 +2,11 @@
class Usher
class Node
- Response = Struct.new(:path, :params)
+ Response = Struct.new(:path, :params, :remaining_path, :matched_path)
attr_reader :lookup, :greedy_lookup
attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods
def initialize(parent, value)
@@ -24,11 +24,11 @@
def upgrade_greedy_lookup
@greedy_lookup = FuzzyHash.new(@greedy_lookup)
end
def depth
- @depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
+ @depth ||= @parent.is_a?(Node) ? @parent.depth + 1 : 0
end
def greedy?
!@greedy_lookup.empty?
end
@@ -53,69 +53,49 @@
end
end
def add(route)
route.paths.each do |path|
- parts = path.parts.dup
- request_methods.each do |type|
- parts.push(Route::RequestMethod.new(type, route.conditions[type])) if route.conditions && route.conditions.key?(type)
- end
-
- current_node = self
- until parts.size.zero?
- key = parts.shift
- target_node = case key
- when Route::RequestMethod
- current_node.upgrade_lookup if key.value.is_a?(Regexp)
- if current_node.exclusive_type == key.type
- current_node.lookup[key.value] ||= Node.new(current_node, key)
- elsif current_node.lookup.empty?
- current_node.exclusive_type = key.type
- current_node.lookup[key.value] ||= Node.new(current_node, key)
- else
- parts.unshift(key)
- current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
- end
- else
- case key
- when Route::Variable
- (upgrade_method, lookup_method) = case key
- when Route::Variable::Greedy
- [:upgrade_greedy_lookup, :greedy_lookup]
- else
- [:upgrade_lookup, :lookup]
- end
-
- if key.regex_matcher
- current_node.send(upgrade_method)
- current_node.send(lookup_method)[key.regex_matcher] ||= Node.new(current_node, key)
- else
- current_node.send(lookup_method)[nil] ||= Node.new(current_node, key)
- end
- else
- current_node.upgrade_lookup if key.is_a?(Regexp)
- current_node.lookup[key] ||= Node.new(current_node, key)
- end
- end
- current_node = target_node
- end
- current_node.terminates = path
+ set_path_with_destination(path)
end
- route
end
+ def delete(route)
+ route.paths.each do |path|
+ set_path_with_destination(path, nil)
+ end
+ end
+
+ def unique_routes(node = self, routes = [])
+ routes << node.terminates.route if node.terminates
+ node.lookup.values.each do |v|
+ unique_routes(v, routes)
+ end
+ node.greedy_lookup.values.each do |v|
+ unique_routes(v, routes)
+ end
+ routes.uniq!
+ routes
+ end
+
def find(usher, request, original_path, path, params = [], position = 0)
if exclusive_type
[lookup[request.send(exclusive_type)], lookup[nil]].each do |n|
if n && (ret = n.find(usher, request, original_path, path.dup, params.dup, position))
return ret
end
end
- elsif path.size.zero? && terminates?
- Response.new(terminates, params)
+ nil
+ elsif terminates? && (path.size.zero? || terminates.route.partial_match?)
+ if terminates.route.partial_match?
+ Response.new(terminates, params, original_path[position, original_path.size], original_path[0, position])
+ else
+ Response.new(terminates, params, nil, original_path)
+ end
+
elsif !path.size.zero? && (greedy? && (match_with_result_output = greedy_lookup.match_with_result(whole_path = original_path[position, original_path.size])))
- next_path, matched_part = match_with_result_output
+ next_path, matched_part = match_with_result_output
position += matched_part.size
params << [next_path.value.name, whole_path.slice!(0, matched_part.size)]
next_path.find(usher, request, original_path, whole_path.size.zero? ? whole_path : usher.splitter.url_split(whole_path), params, position)
elsif !path.size.zero? && (next_part = lookup[part = path.shift] || lookup[nil])
position += part.size
@@ -155,7 +135,53 @@
else
nil
end
end
+ private
+ def set_path_with_destination(path, destination = path)
+ parts = path.parts.dup
+ request_methods.each do |type|
+ parts.push(Route::RequestMethod.new(type, path.route.conditions[type])) if path.route.conditions && path.route.conditions.key?(type)
+ end
+
+ current_node = self
+ until parts.size.zero?
+ key = parts.shift
+ target_node = case key
+ when Route::RequestMethod
+ current_node.upgrade_lookup if key.value.is_a?(Regexp)
+ if current_node.exclusive_type == key.type
+ current_node.lookup[key.value] ||= Node.new(current_node, key)
+ elsif current_node.lookup.empty?
+ current_node.exclusive_type = key.type
+ current_node.lookup[key.value] ||= Node.new(current_node, key)
+ else
+ parts.unshift(key)
+ current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
+ end
+ when Route::Variable
+ upgrade_method, lookup_method = case key
+ when Route::Variable::Greedy
+ [:upgrade_greedy_lookup, :greedy_lookup]
+ else
+ [:upgrade_lookup, :lookup]
+ end
+
+ if key.regex_matcher
+ current_node.send(upgrade_method)
+ current_node.send(lookup_method)[key.regex_matcher] ||= Node.new(current_node, key)
+ else
+ current_node.send(lookup_method)[nil] ||= Node.new(current_node, key)
+ end
+ else
+ current_node.upgrade_lookup if key.is_a?(Regexp)
+ current_node.lookup[key] ||= Node.new(current_node, key)
+ end
+ current_node = target_node
+ end
+ current_node.terminates = destination
+ end
+
+
end
end