Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove StringOfJson #180

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ This `route` variant allows you to invoke a call if possible, without raising an

`router: RpcRouter`: The router object that contains the RPCs.

`data: StringOfJson`: A raw `Json document` that matches the expected format as defined above.
`data: JsonString`: A raw `Json document` that matches the expected format as defined above.

`fut: var Future[StringOfJson]`: The stringified JSON RPC result or a JSON wrapped error.
`fut: var Future[JsonString]`: The stringified JSON RPC result or a JSON wrapped error.

#### Returns

Expand Down Expand Up @@ -397,7 +397,7 @@ Additionally, the following two procedures are useful:
`name: string`: the method to be called
`params: JsonNode`: The parameters to the RPC call
Returning
`Future[StringOfJson]`: A wrapper for the result `Json document` and a flag to indicate if this contains an error.
`Future[JsonString]`: A wrapper for the result `Json document` and a flag to indicate if this contains an error.

Note: Although `call` isn't necessary for a client to function, it allows RPC signatures to be used by the `createRpcSigs`.

Expand Down
8 changes: 4 additions & 4 deletions json_rpc/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export

type
RpcClient* = ref object of RootRef
awaiting*: Table[RequestId, Future[StringOfJson]]
awaiting*: Table[RequestId, Future[JsonString]]
lastId: int
onDisconnect*: proc() {.gcsafe, raises: [].}

Expand All @@ -53,12 +53,12 @@ proc getNextId*(client: RpcClient): RequestId =
RequestId(kind: riNumber, num: client.lastId)

method call*(client: RpcClient, name: string,
params: RequestParamsTx): Future[StringOfJson]
params: RequestParamsTx): Future[JsonString]
{.base, gcsafe, async.} =
doAssert(false, "`RpcClient.call` not implemented")

method call*(client: RpcClient, name: string,
params: JsonNode): Future[StringOfJson]
params: JsonNode): Future[JsonString]
{.base, gcsafe, async.} =

await client.call(name, params.paramsTx)
Expand All @@ -78,7 +78,7 @@ proc processMessage*(client: RpcClient, line: string): Result[void, string] =
if response.id.isNone:
return err("missing or invalid response id")

var requestFut: Future[StringOfJson]
var requestFut: Future[JsonString]
let id = response.id.get
if not client.awaiting.pop(id, requestFut):
return err("Cannot find message id \"" & $id & "\"")
Expand Down
10 changes: 8 additions & 2 deletions json_rpc/clients/httpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ proc newRpcHttpClient*(
RpcHttpClient.new(maxBodySize, secure, getHeaders, flags)

method call*(client: RpcHttpClient, name: string,
params: RequestParamsTx): Future[StringOfJson]
params: RequestParamsTx): Future[JsonString]
{.async, gcsafe.} =
doAssert client.httpSession != nil
if client.httpAddress.isErr:
Expand All @@ -74,18 +74,24 @@ method call*(client: RpcHttpClient, name: string,
var req: HttpClientRequestRef
var res: HttpClientResponseRef

template used(x: typed) =
# silence unused warning
discard

template closeRefs() =
# We can't trust try/finally in async/await in all nim versions, so we
# do it manually instead
if req != nil:
try:
await req.closeWait()
except CatchableError as exc: # shouldn't happen
used(exc)
debug "Error closing JSON-RPC HTTP resuest/response", err = exc.msg
if res != nil:
try:
await res.closeWait()
except CatchableError as exc: # shouldn't happen
used(exc)
debug "Error closing JSON-RPC HTTP resuest/response", err = exc.msg

debug "Sending message to RPC server",
Expand Down Expand Up @@ -131,7 +137,7 @@ method call*(client: RpcHttpClient, name: string,

# completed by processMessage - the flow is quite weird here to accomodate
# socket and ws clients, but could use a more thorough refactoring
var newFut = newFuture[StringOfJson]()
var newFut = newFuture[JsonString]()
# add to awaiting responses
client.awaiting[id] = newFut

Expand Down
4 changes: 2 additions & 2 deletions json_rpc/clients/socketclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ proc newRpcSocketClient*: RpcSocketClient =
RpcSocketClient.new()

method call*(self: RpcSocketClient, name: string,
params: RequestParamsTx): Future[StringOfJson] {.async, gcsafe.} =
params: RequestParamsTx): Future[JsonString] {.async, gcsafe.} =
## Remotely calls the specified RPC method.
let id = self.getNextId()
var value = requestTxEncode(name, params, id) & "\r\n"
Expand All @@ -45,7 +45,7 @@ method call*(self: RpcSocketClient, name: string,
"Transport is not initialised (missing a call to connect?)")

# completed by processMessage.
var newFut = newFuture[StringOfJson]()
var newFut = newFuture[JsonString]()
# add to awaiting responses
self.awaiting[id] = newFut

Expand Down
4 changes: 2 additions & 2 deletions json_rpc/clients/websocketclientimpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ proc newRpcWebSocketClient*(
RpcWebSocketClient.new(getHeaders)

method call*(self: RpcWebSocketClient, name: string,
params: RequestParamsTx): Future[StringOfJson] {.async, gcsafe.} =
params: RequestParamsTx): Future[JsonString] {.async, gcsafe.} =
## Remotely calls the specified RPC method.
let id = self.getNextId()
var value = requestTxEncode(name, params, id) & "\r\n"
Expand All @@ -48,7 +48,7 @@ method call*(self: RpcWebSocketClient, name: string,
"Transport is not initialised (missing a call to connect?)")

# completed by processMessage.
var newFut = newFuture[StringOfJson]()
var newFut = newFuture[JsonString]()
# add to awaiting responses
self.awaiting[id] = newFut

Expand Down
4 changes: 2 additions & 2 deletions json_rpc/private/client_handler_wrapper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ proc setupConversion(reqParams, params: NimNode): NimNode =

for parName, parType in paramsIter(params):
result.add quote do:
`reqParams`.positional.add encode(JrpcConv, `parName`).StringOfJson
`reqParams`.positional.add encode(JrpcConv, `parName`).JsonString

proc createRpcFromSig*(clientType, rpcDecl: NimNode, alias = NimNode(nil)): NimNode =
# Each input parameter in the rpc signature is converted
Expand Down Expand Up @@ -83,7 +83,7 @@ proc createRpcFromSig*(clientType, rpcDecl: NimNode, alias = NimNode(nil)): NimN
# populate request params
`setup`

# `rpcResult` is of type `StringOfJson`
# `rpcResult` is of type `JsonString`
let `rpcResult` = await `clientIdent`.call(`pathStr`, `reqParams`)
`maybeWrap`

Expand Down
3 changes: 0 additions & 3 deletions json_rpc/private/jrpc_conv.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import
export
json_serialization

type
StringOfJson* = JsonString

createJsonFlavor JrpcConv,
requireAllFields = false

Expand Down
8 changes: 4 additions & 4 deletions json_rpc/private/server_handler_wrapper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ proc wrapServerHandler*(methName: string, params, procBody, procWrapper: NimNode
## procBody
## return retVal
##
## proc rpcWrapper(params: RequestParamsRx): Future[StringOfJson] =
## proc rpcWrapper(params: RequestParamsRx): Future[JsonString] =
## type
## RpcType = object
## paramA: ParamAType
Expand All @@ -237,7 +237,7 @@ proc wrapServerHandler*(methName: string, params, procBody, procWrapper: NimNode
## rpcVar = params.unpack(named of RpcType)
##
## let res = await rpcHandler(rpcVar.paramA, rpcVar.paramB)
## return JrpcConv.encode(res).StringOfJson
## return JrpcConv.encode(res).JsonString

let
params = params.ensureReturnType()
Expand Down Expand Up @@ -287,13 +287,13 @@ proc wrapServerHandler*(methName: string, params, procBody, procWrapper: NimNode
doEncode = quote do: encode(JrpcConv, `awaitedResult`)
maybeWrap =
if returnType.noWrap: awaitedResult
else: ident"StringOfJson".newCall doEncode
else: ident"JsonString".newCall doEncode
executeCall = newCall(handlerName, executeParams)

result = newStmtList()
result.add handler
result.add quote do:
proc `procWrapper`(`paramsIdent`: RequestParamsRx): Future[StringOfJson] {.async, gcsafe.} =
proc `procWrapper`(`paramsIdent`: RequestParamsRx): Future[JsonString] {.async, gcsafe.} =
# Avoid 'yield in expr not lowered' with an intermediate variable.
# See: https://github.com/nim-lang/Nim/issues/17849
`setup`
Expand Down
2 changes: 1 addition & 1 deletion json_rpc/private/shared_wrapper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func ensureReturnType*(params: NimNode): NimNode =
func noWrap*(returnType: NimNode): bool =
## Condition when return type should not be encoded
## to Json
returnType.repr == "StringOfJson" or
returnType.repr == "JsonString" or
returnType.repr == "JsonString"

func paramsTx*(params: JsonNode): RequestParamsTx =
Expand Down
16 changes: 8 additions & 8 deletions json_rpc/router.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export

type
# Procedure signature accepted as an RPC call by server
RpcProc* = proc(params: RequestParamsRx): Future[StringOfJson]
RpcProc* = proc(params: RequestParamsRx): Future[JsonString]
{.gcsafe, raises: [CatchableError].}

RpcRouter* = object
Expand Down Expand Up @@ -51,7 +51,7 @@ func invalidRequest(msg: string): ResponseError =
func methodNotFound(msg: string): ResponseError =
ResponseError(code: METHOD_NOT_FOUND, message: msg)

func serverError(msg: string, data: StringOfJson): ResponseError =
func serverError(msg: string, data: JsonString): ResponseError =
ResponseError(code: SERVER_ERROR, message: msg, data: Opt.some(data))

func somethingError(code: int, msg: string): ResponseError =
Expand Down Expand Up @@ -92,7 +92,7 @@ proc wrapError(code: int, msg: string, id: RequestId): ResponseTx =
error: somethingError(code, msg),
)

proc wrapReply(res: StringOfJson, id: RequestId): ResponseTx =
proc wrapReply(res: JsonString, id: RequestId): ResponseTx =
ResponseTx(
id: id,
kind: rkResult,
Expand Down Expand Up @@ -134,12 +134,12 @@ proc route*(router: RpcRouter, req: RequestRx):
debug "Error occurred within RPC",
methodName = methodName, err = err.msg
return serverError(methodName & " raised an exception",
escapeJson(err.msg).StringOfJson).
escapeJson(err.msg).JsonString).
wrapError(req.id)

proc wrapErrorAsync*(code: int, msg: string):
Future[StringOfJson] {.gcsafe, async: (raises: []).} =
return wrapError(code, msg).StringOfJson
Future[JsonString] {.gcsafe, async: (raises: []).} =
return wrapError(code, msg).JsonString

proc route*(router: RpcRouter, data: string):
Future[string] {.gcsafe, async: (raises: []).} =
Expand Down Expand Up @@ -172,8 +172,8 @@ proc route*(router: RpcRouter, data: string):

return reply

proc tryRoute*(router: RpcRouter, data: StringOfJson,
fut: var Future[StringOfJson]): Result[void, string] =
proc tryRoute*(router: RpcRouter, data: JsonString,
fut: var Future[JsonString]): Result[void, string] =
## Route to RPC, returns false if the method or params cannot be found.
## Expects json input and returns json output.
when defined(nimHasWarnBareExcept):
Expand Down
2 changes: 1 addition & 1 deletion json_rpc/rpcproxy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ proc getWebSocketClientConfig*(
ClientConfig(kind: WebSocket, wsUri: uri, compression: compression, flags: flags)

proc proxyCall(client: RpcClient, name: string): RpcProc =
return proc (params: RequestParamsRx): Future[StringOfJson] {.gcsafe, async.} =
return proc (params: RequestParamsRx): Future[JsonString] {.gcsafe, async.} =
let res = await client.call(name, params.toTx)
return res

Expand Down
4 changes: 2 additions & 2 deletions json_rpc/server.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ template hasMethod*(server: RpcServer, methodName: string): bool =

proc executeMethod*(server: RpcServer,
methodName: string,
params: RequestParamsTx): Future[StringOfJson]
params: RequestParamsTx): Future[JsonString]
{.gcsafe, raises: [JsonRpcError].} =

let
Expand All @@ -58,7 +58,7 @@ proc executeMethod*(server: RpcServer,

proc executeMethod*(server: RpcServer,
methodName: string,
args: JsonNode): Future[StringOfJson]
args: JsonNode): Future[JsonString]
{.gcsafe, raises: [JsonRpcError].} =

let params = paramsTx(args)
Expand Down
6 changes: 3 additions & 3 deletions tests/private/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
import
../../json_rpc/router

converter toStr*(value: distinct (string|StringOfJson)): string = string(value)
converter toStr*(value: distinct (string|JsonString)): string = string(value)

template `==`*(a: StringOfJson, b: JsonNode): bool =
template `==`*(a: JsonString, b: JsonNode): bool =
parseJson(string a) == b

template `==`*(a: JsonNode, b: StringOfJson): bool =
template `==`*(a: JsonNode, b: JsonString): bool =
a == parseJson(string b)
1 change: 0 additions & 1 deletion tests/test_router_rpc.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import
unittest2,
../json_rpc/router,
json_serialization/stew/results,
json_serialization/std/options

var server = RpcRouter()
Expand Down
4 changes: 2 additions & 2 deletions tests/testethcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ server.rpc(rpcDynamicName "testReturnUint256") do() -> UInt256:
let r: UInt256 = "0x1234567890abcdef".parse(UInt256, 16)
return r

proc testLocalCalls: Future[seq[StringOfJson]] =
proc testLocalCalls: Future[seq[JsonString]] =
## Call RPCs created with `rpc` locally.
## This simply demonstrates async calls of the procs generated by the `rpc` macro.
let
uint256Param = server.executeMethod("rpc.uint256Param", %[%"0x1234567890"])
returnUint256 = server.executeMethod("rpc.testReturnUint256", %[])
return all(uint256Param, returnUint256)

proc testRemoteUInt256: Future[seq[StringOfJson]] =
proc testRemoteUInt256: Future[seq[JsonString]] =
## Call function remotely on server, testing `stint` types
let
uint256Param = client.call("rpc.uint256Param", %[%"0x1234567890"])
Expand Down