diff --git a/eth-rpc/server/servertypes.nim b/eth-rpc/server/servertypes.nim index 8829701..05c1f07 100644 --- a/eth-rpc/server/servertypes.nim +++ b/eth-rpc/server/servertypes.nim @@ -81,6 +81,15 @@ macro multiRemove(s: string, values: varargs[string]): untyped = body.add multiReplaceCall 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 = var paramTemplates = newStmtList() 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: # TODO: transform result type and/or return to json discard - # + + var paramsIdent = ident"params" + for i in 1.. `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 let @@ -132,16 +161,24 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped = when isMainModule: import unittest var s = newRpcServer("localhost") - s.on("the/path") do(a: int, b: string): - var node = %"test" - result = node - s.on("the/path2") do() -> int: - echo "hello2" - s.on("the/path3"): + s.on("the/path1"): echo "hello3" 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": 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/path3") + test "Processing arrays": + let r = waitfor thepath4(%[1, 2, 3]) + check r == %[1, 2, 3, 0, 0, 0] \ No newline at end of file