syndicate-nim/tests/test_chat.nim

67 lines
1.9 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, asyncfile, os, parseopt]
import preserves, syndicate, syndicate/protocols/transportAddress
type
Present {.preservesRecord: "Present".} = object
username: string
Says {.preservesRecord: "Says".} = object
who, what: string
proc readStdin(facet: Facet; ds: Cap; username: string) =
let file = openAsync("/dev/stdin")
onStop(facet) do (turn: var Turn): close(file)
close(stdin)
proc readLine() {.gcsafe.} =
let future = readLine(file)
addCallback(future, facet) do (turn: var Turn):
var msg = read(future)
message(turn, ds, Says(who: username, what: msg))
readLine()
readLine()
proc chat(turn: var Turn; ds: Cap; username: string) =
during(turn, ds, ?Present) do (who: string):
echo who, " joined"
do:
echo who, " left"
onMessage(turn, ds, ?Says) do (who: string, what: string):
echo who, ": ", what
discard publish(turn, ds, Present(username: username))
readStdin(turn.facet, ds, username)
proc main =
var
transport: Preserve[void]
cap: Preserve[Cap]
username = getEnv("USER")
calledWithArguments = false
for kind, key, val in getopt():
calledWithArguments = true
if kind == cmdLongOption:
case key
of "address", "transport":
transport = parsePreserves(val)
of "cap", "sturdy":
cap = parsePreserves(val, Cap)
of "user", "username":
username = val
if calledWithArguments:
runActor("chat") do (root: Cap; turn: var Turn):
var
unixAddr: transportAddress.Unix
tcpAddr: transportAddress.Tcp
if fromPreserve(unixAddr, transport):
connect(turn, unixAddr, cap) do (turn: var Turn; ds: Cap):
chat(turn, ds, username)
elif fromPreserve(tcpAddr, transport):
connect(turn, tcpAddr, cap) do (turn: var Turn; ds: Cap):
chat(turn, ds, username)
main()