Add param handling to command router
This commit is contained in:
parent
1f494c5a63
commit
1eea71177f
2
Makefile
2
Makefile
@ -24,5 +24,5 @@ format:
|
||||
|
||||
.PHONY: spec
|
||||
spec: format
|
||||
./crystal spec --no-debug --warnings all --error-on-warnings
|
||||
./crystal spec --no-debug --warnings all --error-on-warnings --error-trace
|
||||
|
||||
|
@ -2,13 +2,42 @@ require "./spec_helper"
|
||||
require "../src/cli/*"
|
||||
|
||||
describe CLI::CommandRouter do
|
||||
it "should handle simple command" do
|
||||
it "should handle simple command as block" do
|
||||
router = CLI::CommandRouter.new
|
||||
x = 10
|
||||
router.add "plus" do
|
||||
router.add "plus" do |p|
|
||||
x += 5
|
||||
end
|
||||
router.handle "plus"
|
||||
x.should eq 15
|
||||
end
|
||||
|
||||
it "should handle simple command as proc" do
|
||||
router = CLI::CommandRouter.new
|
||||
x = 10
|
||||
cb = ->(params : Hash(String, String)) { x += 5 }
|
||||
router.add "plus", &cb
|
||||
router.handle "plus"
|
||||
x.should eq 15
|
||||
end
|
||||
|
||||
it "should handle command with argument" do
|
||||
router = CLI::CommandRouter.new
|
||||
x = 10
|
||||
router.add "plus {x}" do |params|
|
||||
x += params["x"].to_i32
|
||||
end
|
||||
router.handle "plus 5"
|
||||
x.should eq 15
|
||||
end
|
||||
|
||||
it "should handle command with three arguments" do
|
||||
router = CLI::CommandRouter.new
|
||||
x = 0
|
||||
router.add "plus {x} {y} {z}" do |p|
|
||||
x = p["x"].to_i32 + p["y"].to_i32 + p["z"].to_i32
|
||||
end
|
||||
router.handle "plus 1 3 6"
|
||||
x.should eq 10
|
||||
end
|
||||
end
|
||||
|
@ -1,17 +1,42 @@
|
||||
class CLI::CommandRouter
|
||||
def initialize
|
||||
@mappings = [] of {String, Proc(Nil)}
|
||||
@mappings = [] of {Regex, Proc(Hash(String, String), Nil)}
|
||||
end
|
||||
|
||||
def add(route, &block)
|
||||
@mappings.push({route, block})
|
||||
def add(route, &block : Hash(String, String) -> Nil)
|
||||
pattern = route_to_regex(route)
|
||||
@mappings.push({pattern, block})
|
||||
end
|
||||
|
||||
def handle(command)
|
||||
@mappings.each do |i|
|
||||
if i[0] == command
|
||||
i[1].call
|
||||
@mappings.each do |handler|
|
||||
handle_pattern(command, *handler)
|
||||
end
|
||||
end
|
||||
|
||||
private def handle_pattern(command, pattern, cb)
|
||||
m = command.match(pattern)
|
||||
return if m.nil?
|
||||
groups = m.named_captures
|
||||
nil_groups = groups.select { |k, v| v.nil? }
|
||||
return if nil_groups.size != 0
|
||||
params = groups.transform_values { |v| v.to_s }
|
||||
cb.call params
|
||||
end
|
||||
|
||||
private def route_to_regex(route) : Regex
|
||||
vals = route.partition(/\{[a-z]+?\}/)
|
||||
param = vals[1].lstrip('{').rstrip('}')
|
||||
result = ""
|
||||
if vals[0] != ""
|
||||
result += Regex.escape(vals[0])
|
||||
end
|
||||
if vals[1] != ""
|
||||
result += sprintf "(?P<%s>.+?)", param
|
||||
end
|
||||
if vals[2] != ""
|
||||
result += route_to_regex(vals[2]).source
|
||||
end
|
||||
Regex.new(result)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user