diff --git a/eth-rpc/server/servertypes.nim b/eth-rpc/server/servertypes.nim index 05c1f07..d08ea3b 100644 --- a/eth-rpc/server/servertypes.nim +++ b/eth-rpc/server/servertypes.nim @@ -91,7 +91,9 @@ proc jsonGetFunc(paramType: string): NimNode = else: result = nil macro on*(server: var RpcServer, path: string, body: untyped): untyped = - var paramTemplates = newStmtList() + var + paramTemplates = newStmtList() + expectedParams = 0 let parameters = body.findChild(it.kind == nnkFormalParams) if not parameters.isNil: # process parameters of body into json fetch templates @@ -101,6 +103,7 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped = discard var paramsIdent = ident"params" + expectedParams = parameters.len - 1 for i in 1.. `name`.len: - raise newException(ValueError, "Array longer than parameter allows. Expected " & $`arrayLen` & ", data length is " & $`paramsIdent`.len) + raise newException(ValueError, "Array longer than parameter allows. Expected " & $`arrayLen` & ", data length is " & $`paramsIdent`.elems[`pos`].len) else: - for `idx` in 0 ..< `paramsIdent`.len: - `name`[`idx`] = `arrayType`(`paramsIdent`.elems[`idx`].`getFunc`) - ) + for `idx` in 0 ..< `paramsIdent`.elems[`pos`].len: + `name`[`idx`] = `arrayType`(`paramsIdent`.elems[`pos`].elems[`idx`].`getFunc`) + ) + else: + paramType.expectLen 2 + let + seqType = paramType[1] + getFunc = jsonGetFunc($seqType) + paramTemplates.add(quote do: + if `paramsIdent`.elems[`pos`].kind != JArray: + raise newException(ValueError, "Expected array but got " & $`paramsIdent`.elems[`pos`].kind) + var `name` = newSeq[`seqType`](`paramsIdent`.elems[`pos`].len) + for `idx` in 0 ..< `paramsIdent`.elems[`pos`].len: + `name`[`idx`] = `seqType`(`paramsIdent`.elems[`pos`].elems[`idx`].`getFunc`) + ) else: # other types var getFuncName = jsonGetFunc($paramType) @@ -142,7 +166,6 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped = paramTemplates.add(quote do: var `name`: `paramType` = `paramsIdent`.elems[`pos`].`getFunc` ) - # create RPC proc let pathStr = $path @@ -152,11 +175,20 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped = if body.kind == nnkStmtList: procBody = body else: procBody = body.body # + var checkTypeError: NimNode + if expectedParams > 0: + checkTypeError = quote do: + if `paramsIdent`.kind != JArray: + raise newException(ValueError, "Expected array but got " & $`paramsIdent`.kind) + else: checkTypeError = newStmtList() + result = quote do: proc `procName`*(`paramsIdent`: JsonNode): Future[JsonNode] {.async.} = + `checkTypeError` `paramTemplates` `procBody` `server`.register(`path`, `procName`) + echo result.repr when isMainModule: import unittest @@ -171,6 +203,13 @@ when isMainModule: result = node s.on("the/path4") do(arr: array[6, byte], b: string): var res = newJArray() + for item in arr: + res.add %int(item) + res.add %b + result = %res + s.on("the/path5") do(b: string, arr: seq[int]): + var res = newJArray() + res.add %b for item in arr: res.add %int(item) result = res @@ -179,6 +218,14 @@ when isMainModule: 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 + test "Array/seq parameters": + let r1 = waitfor thepath4(%[%[1, 2, 3], %"hello"]) + var ckR1 = %[1, 2, 3, 0, 0, 0] + ckR1.elems.add %"hello" + check r1 == ckR1 + + let r2 = waitfor thepath5(%[%"abc", %[1, 2, 3, 4, 5]]) + var ckR2 = %["abc"] + for i in 0..4: ckR2.add %(i + 1) + check r2 == ckR2 + \ No newline at end of file