diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/journey/routes.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/journey/routes.rb | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/actionpack/lib/action_dispatch/journey/routes.rb b/actionpack/lib/action_dispatch/journey/routes.rb new file mode 100644 index 0000000000..32829a1f20 --- /dev/null +++ b/actionpack/lib/action_dispatch/journey/routes.rb @@ -0,0 +1,76 @@ +module ActionDispatch + module Journey # :nodoc: + # The Routing table. Contains all routes for a system. Routes can be + # added to the table by calling Routes#add_route. + class Routes # :nodoc: + include Enumerable + + attr_reader :routes, :named_routes + + def initialize + @routes = [] + @named_routes = {} + @ast = nil + @partitioned_routes = nil + @simulator = nil + end + + def length + @routes.length + end + alias :size :length + + def last + @routes.last + end + + def each(&block) + routes.each(&block) + end + + def clear + routes.clear + end + + def partitioned_routes + @partitioned_routes ||= routes.partition { |r| + r.path.anchored && r.ast.grep(Nodes::Symbol).all? { |n| n.default_regexp? } + } + end + + def ast + return @ast if @ast + return if partitioned_routes.first.empty? + + asts = partitioned_routes.first.map { |r| r.ast } + @ast = Nodes::Or.new(asts) + end + + def simulator + return @simulator if @simulator + + gtg = GTG::Builder.new(ast).transition_table + @simulator = GTG::Simulator.new(gtg) + end + + # Add a route to the routing table. + def add_route(app, path, conditions, defaults, name = nil) + route = Route.new(name, app, path, conditions, defaults) + + route.precedence = routes.length + routes << route + named_routes[name] = route if name && !named_routes[name] + clear_cache! + route + end + + private + + def clear_cache! + @ast = nil + @partitioned_routes = nil + @simulator = nil + end + end + end +end |