mirror of
https://github.com/status-im/nim-json-rpc.git
synced 2025-02-24 10:18:15 +00:00
Arrays now marshalled to native types and other params are prefetched
This commit is contained in:
parent
4acd6b3ee6
commit
c48167a1cc
@ -81,6 +81,15 @@ macro multiRemove(s: string, values: varargs[string]): untyped =
|
|||||||
body.add multiReplaceCall
|
body.add multiReplaceCall
|
||||||
result = newBlockStmt(body)
|
result = newBlockStmt(body)
|
||||||
|
|
||||||
|
proc jsonGetFunc(paramType: string): NimNode =
|
||||||
|
case paramType
|
||||||
|
of "string": result = ident"getStr"
|
||||||
|
of "int": result = ident"getInt"
|
||||||
|
of "float": result = ident"getFloat"
|
||||||
|
of "bool": result = ident"getBool"
|
||||||
|
of "byte": result = ident"getInt"
|
||||||
|
else: result = nil
|
||||||
|
|
||||||
macro on*(server: var RpcServer, path: string, body: untyped): untyped =
|
macro on*(server: var RpcServer, path: string, body: untyped): untyped =
|
||||||
var paramTemplates = newStmtList()
|
var paramTemplates = newStmtList()
|
||||||
let parameters = body.findChild(it.kind == nnkFormalParams)
|
let parameters = body.findChild(it.kind == nnkFormalParams)
|
||||||
@ -90,29 +99,49 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped =
|
|||||||
if resType.kind != nnkEmpty:
|
if resType.kind != nnkEmpty:
|
||||||
# TODO: transform result type and/or return to json
|
# TODO: transform result type and/or return to json
|
||||||
discard
|
discard
|
||||||
#
|
|
||||||
|
var paramsIdent = ident"params"
|
||||||
|
|
||||||
for i in 1..<parameters.len:
|
for i in 1..<parameters.len:
|
||||||
|
let pos = i - 1 # first index is return type
|
||||||
parameters[i].expectKind nnkIdentDefs
|
parameters[i].expectKind nnkIdentDefs
|
||||||
#
|
|
||||||
let
|
# take user's parameter name for template
|
||||||
name = parameters[i][0] # take user's parameter name for template
|
let name = parameters[i][0]
|
||||||
paramType = parameters[i][1]
|
var paramType = parameters[i][1]
|
||||||
var getFuncName: string
|
|
||||||
case $paramType
|
# TODO: Object marshalling
|
||||||
of "string": getFuncName = "getStr"
|
|
||||||
of "int": getFuncName = "getInt"
|
if paramType.kind == nnkBracketExpr:
|
||||||
of "float": getFuncName = "getFloat"
|
# process array parameters
|
||||||
of "bool": getFuncName = "getBool"
|
assert $paramType[0] == "array"
|
||||||
# TODO: array, object
|
paramType.expectLen 3
|
||||||
else: discard
|
let
|
||||||
# fetch parameter
|
arrayType = paramType[2]
|
||||||
let
|
arrayLen = paramType[1]
|
||||||
getFunc = ident(getFuncName)
|
getFunc = jsonGetFunc($arrayType)
|
||||||
pos = i - 1 # first index is return type
|
idx = ident"i"
|
||||||
paramsIdent = ident"params"
|
# marshall json array to requested types
|
||||||
paramTemplates.add(quote do:
|
# TODO: Replace length exception with async error return value
|
||||||
template `name`: `paramType` = `paramsIdent`.elems[`pos`].`getFunc`
|
# We would need to pass the server in parameters to access the socket
|
||||||
)
|
paramTemplates.add(quote do:
|
||||||
|
var `name`: `paramType`
|
||||||
|
block:
|
||||||
|
if `paramsIdent`.len > `name`.len:
|
||||||
|
raise newException(ValueError, "Array longer than parameter allows. Expected " & $`arrayLen` & ", data length is " & $`paramsIdent`.len)
|
||||||
|
else:
|
||||||
|
for `idx` in 0 ..< `paramsIdent`.len:
|
||||||
|
`name`[`idx`] = `arrayType`(`paramsIdent`.elems[`idx`].`getFunc`)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# other types
|
||||||
|
var getFuncName = jsonGetFunc($paramType)
|
||||||
|
assert getFuncName != nil
|
||||||
|
# fetch parameter
|
||||||
|
let getFunc = newIdentNode($getFuncName)
|
||||||
|
paramTemplates.add(quote do:
|
||||||
|
var `name`: `paramType` = `paramsIdent`.elems[`pos`].`getFunc`
|
||||||
|
)
|
||||||
|
|
||||||
# create RPC proc
|
# create RPC proc
|
||||||
let
|
let
|
||||||
@ -132,16 +161,24 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped =
|
|||||||
when isMainModule:
|
when isMainModule:
|
||||||
import unittest
|
import unittest
|
||||||
var s = newRpcServer("localhost")
|
var s = newRpcServer("localhost")
|
||||||
s.on("the/path") do(a: int, b: string):
|
s.on("the/path1"):
|
||||||
var node = %"test"
|
|
||||||
result = node
|
|
||||||
s.on("the/path2") do() -> int:
|
|
||||||
echo "hello2"
|
|
||||||
s.on("the/path3"):
|
|
||||||
echo "hello3"
|
echo "hello3"
|
||||||
result = %1
|
result = %1
|
||||||
|
s.on("the/path2") do() -> int:
|
||||||
|
echo "hello2"
|
||||||
|
s.on("the/path3") do(a: int, b: string):
|
||||||
|
var node = %"test"
|
||||||
|
result = node
|
||||||
|
s.on("the/path4") do(arr: array[6, byte], b: string):
|
||||||
|
var res = newJArray()
|
||||||
|
for item in arr:
|
||||||
|
res.add %int(item)
|
||||||
|
result = res
|
||||||
suite "Server types":
|
suite "Server types":
|
||||||
test "On macro registration":
|
test "On macro registration":
|
||||||
check s.procs.hasKey("the/path")
|
check s.procs.hasKey("the/path1")
|
||||||
check s.procs.hasKey("the/path2")
|
check s.procs.hasKey("the/path2")
|
||||||
check s.procs.hasKey("the/path3")
|
check s.procs.hasKey("the/path3")
|
||||||
|
test "Processing arrays":
|
||||||
|
let r = waitfor thepath4(%[1, 2, 3])
|
||||||
|
check r == %[1, 2, 3, 0, 0, 0]
|
Loading…
x
Reference in New Issue
Block a user