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
|
.PHONY: spec
|
||||||
spec: format
|
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/*"
|
require "../src/cli/*"
|
||||||
|
|
||||||
describe CLI::CommandRouter do
|
describe CLI::CommandRouter do
|
||||||
it "should handle simple command" do
|
it "should handle simple command as block" do
|
||||||
router = CLI::CommandRouter.new
|
router = CLI::CommandRouter.new
|
||||||
x = 10
|
x = 10
|
||||||
router.add "plus" do
|
router.add "plus" do |p|
|
||||||
x += 5
|
x += 5
|
||||||
end
|
end
|
||||||
router.handle "plus"
|
router.handle "plus"
|
||||||
x.should eq 15
|
x.should eq 15
|
||||||
end
|
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
|
end
|
||||||
|
@ -1,17 +1,42 @@
|
|||||||
class CLI::CommandRouter
|
class CLI::CommandRouter
|
||||||
def initialize
|
def initialize
|
||||||
@mappings = [] of {String, Proc(Nil)}
|
@mappings = [] of {Regex, Proc(Hash(String, String), Nil)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(route, &block)
|
def add(route, &block : Hash(String, String) -> Nil)
|
||||||
@mappings.push({route, block})
|
pattern = route_to_regex(route)
|
||||||
|
@mappings.push({pattern, block})
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle(command)
|
def handle(command)
|
||||||
@mappings.each do |i|
|
@mappings.each do |handler|
|
||||||
if i[0] == command
|
handle_pattern(command, *handler)
|
||||||
i[1].call
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user