Use different JSON schema

This commit is contained in:
Emery Hemingway 2023-07-26 11:45:41 +01:00
parent c65fcc27ed
commit 2303339a26
7 changed files with 34 additions and 42 deletions

View File

@ -2,11 +2,11 @@
## json_translator
Wrapper that executes a command, parses its JSON output, and asserts a Preserves conversion in an `<output …>` record.
Wrapper that executes a command, parses its JSON output, and sends a Preserves conversion as a message in an `<recv @jsonData any>` record.
## json_socket_translator
Utility to communicate with sockets that send and receive lines of JSON using `<sen-json …>` and `<recv-json …>` 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 `<send …>` and `<recv …>` 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 `<connected @socketPath string>`.

View File

@ -1,8 +1,5 @@
version 1 .
Input = <send-json any>.
Output = <recv-json any>.
JsonTranslatorArguments = {
dataspace: #!any
}.

14
src/json_messages.nim Normal file
View File

@ -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

View File

@ -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)

View File

@ -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()))

View File

@ -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()

View File

@ -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))