diff --git a/README.md b/README.md index 93e5963..c6cfdd0 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ ## json_translator -Wrapper that executes a command, parses its JSON output, and asserts a Preserves conversion in an `` record. +Wrapper that executes a command, parses its JSON output, and sends a Preserves conversion as a message in an `` record. ## json_socket_translator -Utility to communicate with sockets that send and receive lines of JSON using `` and `` messages. Compatible with [mpv](https://mpv.io/), see [mpv.config-example.pr](./mpv.config-example.pr). +Utility to communicate with sockets that send and receive lines of JSON using `` and `` messages. Compatible with [mpv](https://mpv.io/), see [mpv.config-example.pr](./mpv.config-example.pr). Do not send messages immediately to the dataspace passed `json_socket_translator`, wait until it asserts ``. diff --git a/config.prs b/config.prs index 5851592..55e4cd4 100644 --- a/config.prs +++ b/config.prs @@ -1,8 +1,5 @@ version 1 . -Input = . -Output = . - JsonTranslatorArguments = { dataspace: #!any }. diff --git a/src/json_messages.nim b/src/json_messages.nim new file mode 100644 index 0000000..5c9edab --- /dev/null +++ b/src/json_messages.nim @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: ☭ Emery Hemingway +# SPDX-License-Identifier: Unlicense + +import std/json +import preserves, preserves/jsonhooks + +export fromPreserveHook, toPreserveHook + # re-export the hooks so that conversion "just works" + +type + SendJson* {.preservesRecord: "send".} = object + data*: JsonNode + RecvJson* {.preservesRecord: "recv".} = object + data*: JsonNode diff --git a/src/json_socket_translator.nim b/src/json_socket_translator.nim index 6d78b83..3eebf0a 100644 --- a/src/json_socket_translator.nim +++ b/src/json_socket_translator.nim @@ -5,7 +5,7 @@ import std/[asyncdispatch, asyncnet, json] from std/nativesockets import AF_UNIX, SOCK_STREAM, Protocol import preserves, preserves/jsonhooks, syndicate, syndicate/patterns -import ./schema/config +import ./schema/config, ./json_messages runActor("main") do (root: Ref; turn: var Turn): connectStdio(root, turn) @@ -23,16 +23,12 @@ runActor("main") do (root: Ref; turn: var Turn): let socketFacet = turn.facet proc processOutput(fut: Future[string]) {.gcsafe.} = run(socketFacet) do (turn: var Turn): - var data = fut.read.parseJson.toPreserve - message(turn, ds, initRecord("recv-json", data)) + var data = fut.read.parseJson + message(turn, ds, RecvJson(data: data)) socket.recvLine.addCallback(processOutput) socket.recvLine.addCallback(processOutput) - onMessage(turn, ds, ?Input) do (data: Assertion): - var js: JsonNode - if fromPreserve(js, data): - asyncCheck(turn, send(socket, $js & "\n")) - else: - writeLine(stderr, "cannot convert assertion to JSON - ", data) + onMessage(turn, ds, ?SendJson) do (data: JsonNode): + asyncCheck(turn, send(socket, $data & "\n")) do: close(socket) diff --git a/src/json_translator.nim b/src/json_translator.nim index a3f29dd..6b615bb 100644 --- a/src/json_translator.nim +++ b/src/json_translator.nim @@ -7,7 +7,7 @@ import syndicate from preserves/jsonhooks import toPreserveHook -import ./schema/config +import ./schema/config, ./json_messages proc runChild: string = let params = commandLineParams() @@ -19,20 +19,12 @@ proc runChild: string = args = params[1..params.high] try: result = execProcess(command=cmd, args=args, options={poUsePath}) except CatchableError as err: - quit("execProcess failed: " &err.msg) + quit("execProcess failed: " & err.msg) if result == "": stderr.writeLine "no ouput" quit 1 -proc translate(output: string): Assertion = - var js: JsonNode - try: js = parseJson output - except CatchableError as err: - quit("parseJson failed: " &err.msg) - js.toPreserveHook(Ref) - -runActor("main") do (root: Ref; turn: var Turn): +runActor("main") do (root: Cap; turn: var Turn): connectStdio(root, turn) - during(turn, root, ?JsonTranslatorArguments) do (ds: Ref): - message(turn, ds, initRecord[Ref]("recv-json", runChild().translate())) - + during(turn, root, ?JsonTranslatorArguments) do (ds: Cap): + message(turn, ds, RecvJson(data: runChild().parseJson())) diff --git a/src/msg.nim b/src/msg.nim index abdac0c..74df70c 100644 --- a/src/msg.nim +++ b/src/msg.nim @@ -17,10 +17,11 @@ proc envStep: Preserve[Ref] = proc main = let label = getAppFilename().extractFilename discard bootDataspace(label) do (root: Ref; turn: var Turn): - connect(turn, unixSocketPath(), envStep()) do (turn: var Turn; ds: Ref): + let step = envStep() + connect(turn, unixSocketPath(), step) do (turn: var Turn; ds: Ref): message(turn, ds, initRecord(label, map(commandLineParams(), parsePreserves))) - for i in 0..3: poll(20) - # A hack to exit + for _ in 1..4: poll() + quit() main() diff --git a/src/schema/config.nim b/src/schema/config.nim index e40bc8d..752d013 100644 --- a/src/schema/config.nim +++ b/src/schema/config.nim @@ -3,9 +3,6 @@ import preserves type - Output* {.preservesRecord: "recv-json".} = object - `field0`*: Preserve[void] - JsonTranslatorArguments* {.preservesDictionary.} = object `dataspace`* {.preservesEmbedded.}: Preserve[void] @@ -16,15 +13,10 @@ type `dataspace`* {.preservesEmbedded.}: Preserve[void] `socket`*: string - Input* {.preservesRecord: "send-json".} = object - `field0`*: Preserve[void] - -proc `$`*(x: Output | JsonTranslatorArguments | JsonTranslatorConnected | - JsonSocketTranslatorArguments | - Input): string = +proc `$`*(x: JsonTranslatorArguments | JsonTranslatorConnected | + JsonSocketTranslatorArguments): string = `$`(toPreserve(x)) -proc encode*(x: Output | JsonTranslatorArguments | JsonTranslatorConnected | - JsonSocketTranslatorArguments | - Input): seq[byte] = +proc encode*(x: JsonTranslatorArguments | JsonTranslatorConnected | + JsonSocketTranslatorArguments): seq[byte] = encode(toPreserve(x))