diff --git a/json_rpc/jsonmarshal.nim b/json_rpc/jsonmarshal.nim index 426f0ef..3b21e39 100644 --- a/json_rpc/jsonmarshal.nim +++ b/json_rpc/jsonmarshal.nim @@ -116,25 +116,39 @@ proc jsonToNim*(assignIdent, paramType, jsonIdent: NimNode, paramNameStr: string `assignIdent` = `unpackArg`(`jsonIdent`, `paramNameStr`, type(`paramType`)) ) +proc calcActualParamCount(parameters: NimNode): int = + # this proc is needed to calculate the actual parameter count + # not matter what is the declaration form + # e.g. (a: U, b: V) vs. (a, b: T) + for i in 1 ..< parameters.len: + inc(result, parameters[i].len-2) + proc jsonToNim*(parameters, jsonIdent: NimNode): NimNode = # Add code to verify input and load parameters into Nim types result = newStmtList() if not parameters.isNil: # initial parameter array length check - result.expectArrayLen(jsonIdent, parameters.len - 1) + result.expectArrayLen(jsonIdent, calcActualParamCount(parameters)) + # unpack each parameter and provide assignments + var pos = 0 for i in 1 ..< parameters.len: let - pos = i - 1 - paramIdent = parameters[i][0] - paramName = $paramIdent - paramType = parameters[i][1] - jsonElement = quote do: - `jsonIdent`.elems[`pos`] - # declare variable before assignment - result.add(quote do: - var `paramIdent`: `paramType` - ) - # unpack Nim type and assign from json - result.add jsonToNim(paramIdent, paramType, jsonElement, paramName) + param = parameters[i] + paramType = param[^2] + # processing multiple variables of one type + # e.g. (a, b: T), including common (a: U, b: V) form + for j in 0 ..< param.len-2: + let + paramIdent = param[j] + paramName = $paramIdent + jsonElement = quote do: + `jsonIdent`.elems[`pos`] + inc pos + # declare variable before assignment + result.add(quote do: + var `paramIdent`: `paramType` + ) + # unpack Nim type and assign from json + result.add jsonToNim(paramIdent, paramType, jsonElement, paramName) diff --git a/tests/testrpcmacro.nim b/tests/testrpcmacro.nim index 8d10b8c..9138c98 100644 --- a/tests/testrpcmacro.nim +++ b/tests/testrpcmacro.nim @@ -63,6 +63,9 @@ s.rpc("rpc.returntypecomplex") do(i: int) -> Test2: s.rpc("rpc.testreturns") do() -> int: return 1234 +s.rpc("rpc.multivarsofonetype") do(a, b: string) -> string: + result = a & " " & b + # Tests suite "Server types": @@ -75,6 +78,7 @@ suite "Server types": check s.hasMethod("rpc.returntypesimple") check s.hasMethod("rpc.returntypecomplex") check s.hasMethod("rpc.testreturns") + check s.hasMethod("rpc.multivarsofonetype") test "Simple paths": let r = waitFor rpcSimplePath(%[]) @@ -133,5 +137,9 @@ suite "Server types": let res = waitFor rpcDifferentParams(%[%"abc", %1]) # TODO: When errors are proper return values, check error for param name + test "Multiple variables of one type": + let r = waitfor rpcMultiVarsOfOneType(%[%"hello", %"world"]) + check r == %"hello world" + s.stop() s.close()