2020-07-06 15:09:21 +02:00
|
|
|
import strutils
|
|
|
|
from net import IpAddress, parseIpAddress, Port, `$`
|
|
|
|
|
|
|
|
proc parseField(input: string, output: var string) =
|
|
|
|
output = input
|
|
|
|
|
|
|
|
proc parseField[T: SomeUnsignedInt](input: string, output: var T) =
|
|
|
|
let parsed = parseUInt(input)
|
|
|
|
if parsed > T.high:
|
|
|
|
raise newException(ValueError, "Unsigned integer out of range")
|
|
|
|
output = parsed.T
|
|
|
|
|
|
|
|
proc parseField(input: string, output: var IpAddress) =
|
|
|
|
output = parseIpAddress(input)
|
|
|
|
|
|
|
|
proc parseField(input: string, output: var Port) =
|
|
|
|
var portNumber: uint16
|
|
|
|
parseField(input, portNumber)
|
|
|
|
output = Port(portNumber)
|
|
|
|
|
|
|
|
proc parseField[S, T](input: string, output: var array[S, T]) =
|
|
|
|
let parts = input.split(",", S.high)
|
|
|
|
if parts.len != S.high + 1:
|
|
|
|
raise newException(ValueError, "Array has wrong length")
|
|
|
|
for i in 0 .. S.high:
|
|
|
|
parseField(parts[i], output[i])
|
|
|
|
|
2020-07-21 11:10:56 +02:00
|
|
|
proc parseField[T](input: string, output: var seq[T]) =
|
|
|
|
let parts = input.split(",")
|
|
|
|
output = newSeq[T](parts.len)
|
2020-10-12 21:33:05 +02:00
|
|
|
if parts.len > 0:
|
|
|
|
for i in 0 .. parts.len - 1:
|
|
|
|
parseField(parts[i], output[i])
|
2020-07-21 11:10:56 +02:00
|
|
|
|
2020-07-06 15:09:21 +02:00
|
|
|
proc parseField[T: tuple | object](input: string, output: var T) =
|
|
|
|
var fieldCount = 0
|
|
|
|
for _ in output.fields:
|
|
|
|
fieldCount = fieldCount + 1
|
|
|
|
let args = input.parseArgs(fieldCount)
|
|
|
|
var i = 0
|
|
|
|
for value in output.fields:
|
|
|
|
parseField(args[i], value)
|
|
|
|
i.inc
|
|
|
|
|
|
|
|
proc parseArgs*(input: string, count: int, optionalCount = 0): seq[string] =
|
|
|
|
assert(optionalCount <= count)
|
|
|
|
result = input.split("|", count - 1)
|
|
|
|
if result.len < count:
|
|
|
|
if result.len < count - optionalCount:
|
|
|
|
raise newException(ValueError, "invalid message")
|
|
|
|
result.add(repeat("", count - result.len))
|
|
|
|
|
|
|
|
proc parseMessage*[T: tuple | object](input: string): T =
|
|
|
|
parseField(input, result)
|