Add param handling to command router

This commit is contained in:
Anton Vakhrushev
2019-10-04 16:07:03 +03:00
parent 1f494c5a63
commit 1eea71177f
3 changed files with 64 additions and 10 deletions

View File

@ -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
end
@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