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