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