# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[json, options] import pkg/sys/[ioqueue, sockets] import preserves, preserves/jsonhooks, syndicate import ../schema/config, ../json_messages proc translateSocket(facet: Facet; ds: Cap; path: string) {.asyncio.} = var socket = new AsyncConn[Protocol.Unix] conn = connectUnixAsync(path) guard = initGuard(facet) dec = newBufferedDecoder(0) buf = new string #TODO: get a pointer into the decoder alive = true proc kill(turn: var Turn) = alive = false proc setup(turn: var Turn) = # Closure, not CPS. onMessage(turn, ds, ?:SendJson) do (data: JsonNode): if alive: discard trampoline: whelp write(socket[], $data & "\n") else: stderr.writeLine "dropped send of ", data discard publish(turn, ds, initRecord("connected", path.toPreserves)) onStop(facet, kill) run(facet, setup) while alive: # TODO: parse buffer buf[].setLen(0x4000) let n = read(socket[], buf) if n < 1: stderr.writeLine "socket read returned ", n else: buf[].setLen(n) dec.feed(buf[]) var data = dec.parse() if data.isSome: proc send(turn: var Turn) = # Closure, not CPS. message(turn, ds, initRecord("recv", data.get)) run(facet, send) stderr.writeLine "close socket ", path close(socket[]) proc spawnJsonSocketTranslator*(turn: var Turn; root: Cap): Actor {.discardable.} = spawnActor(turn, "json-socket-translator") do (turn: var Turn): during(turn, root, ?:JsonSocketTranslatorArguments) do (ds: Cap, socketPath: string): linkActor(turn, "json-socket-translator") do (turn: var Turn): discard trampoline: whelp translateSocket(turn.facet, ds, socketPath) when isMainModule: import syndicate/relays runActor("main") do (turn: var Turn): resolveEnvironment(turn) do (turn: var Turn; ds: Cap): spawnJsonSocketTranslator(turn, ds)