lib/mvcli/router.rb in mvcli-0.0.1 vs lib/mvcli/router.rb in mvcli-0.0.2

- old
+ new

@@ -5,30 +5,41 @@ RoutingError = Class.new StandardError InvalidRoute = Class.new RoutingError def initialize(actions = nil) @actions = actions || Map.new - @root = Map.new + @routes = [] end - def root(options = {}) - action = options[:to] or fail InvalidRoute, "root routes must specify an action with ':to =>' E.g. root :to => 'foo#bar'" - verbs = [options[:via] || :help].flatten - verbs.each do |verb| - @root[verb] = action - end + def match(options) + pattern, action = options.first + options.delete pattern + @routes << Route.new(pattern, @actions, action, options) end def call(command) - verb = command.argv.first || 'help' - path = command.argv.slice(1..-1) || [] - if path.empty? - if action_name = @root[verb] - if action = @actions[action_name] - return action.call command - end + if route = @routes.find {|r| r.matches? command} + return route.call command + end + fail RoutingError, "no route matches '#{command.argv.join ' '}'" + end + + class Route + def initialize(pattern, actions, action, options = {}) + @pattern, @actions, @action, @options = pattern.to_s, actions, action, options + end + + def matches?(command) + segments = @pattern.split /\s+/ + segments.each_with_index do |s, i| + return false unless command.argv[i] && s.to_s == command.argv[i] end + return true end - fail RoutingError, "#{path.join(':')} does not respond to #{verb}" + + def call(command) + action = @actions[@action] or fail "no action found for #{@action}" + action.call command + end end end end