syndicate_utils/src/syndump.nim

87 lines
2.4 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[os, tables]
import preserves
import syndicate, syndicate/[actors, capabilities, durings, patterns]
proc unixSocketPath: Unix =
result.path = getEnv("SYNDICATE_SOCK")
if result.path == "":
result.path = getEnv("XDG_RUNTIME_DIR", "/run/user/1000") / "dataspace"
proc envStep: Assertion =
var s = getEnv("SYNDICATE_STEP")
if s != "": parsePreserves(s, Cap)
else: capabilities.mint().toPreserve(Cap)
proc parsePattern(pr: Assertion): Pattern =
let
dropSigil = initRecord("lit", "_".toSymbol(Cap))
grabSigil = initRecord("lit", "?".toSymbol(Cap))
var pr = grab(pr).toPreserve(Cap)
apply(pr) do (pr: var Assertion):
if pr == dropSigil:
pr = initRecord[Cap]("_")
elif pr == grabSigil:
pr = initRecord("bind", initRecord[Cap]("_"))
doAssert result.fromPreserve(pr)
proc inputPattern: Pattern =
var args = commandLineParams()
if args.len != 1 or args == @[""]:
quit "expected a single pattern argument"
else:
var
pr: Assertion
input = pop args
try: pr = parsePreserves(input, Cap)
except ValueError:
quit "failed to parse Preserves argument"
result = parsePattern(pr)
type DumpEntity {.final.} = ref object of Entity
assertions: Table[Handle, seq[Assertion]]
proc toLine(values: seq[Assertion]; prefix: char): string =
result = newStringOfCap(1024)
let sep = getEnv("FS", " ")
result.add(prefix)
for v in values:
add(result, sep)
add(result, $v)
add(result, '\n')
method publish(dump: DumpEntity; turn: var Turn; ass: AssertionRef; h: Handle) =
var values = ass.value.sequence
stdout.write(values.toLine('+'))
stdout.flushFile()
dump.assertions[h] = values
method retract(dump: DumpEntity; turn: var Turn; h: Handle) =
var values: seq[Assertion]
if dump.assertions.pop(h, values):
stdout.write(values.toLine('-'))
stdout.flushFile()
method message*(dump: DumpEntity; turn: var Turn; ass: AssertionRef) =
stdout.write(ass.value.sequence.toLine('!'))
stdout.flushFile()
proc exitProc() {.noconv.} =
stdout.write('\n')
quit()
proc main =
let
unix = unixSocketPath()
step = envStep()
pat = inputPattern()
entity = DumpEntity()
runActor("syndex_card") do (root: Cap; turn: var Turn):
connect(turn, unix, step) do (turn: var Turn; ds: Cap):
discard observe(turn, ds, pat, entity)
setControlCHook(exitProc)
main()