# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[asyncdispatch, asyncfile, parseopt] import preserves, syndicate, syndicate/relays 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) if msg == "": quit() message(turn, ds, Says(who: username, what: msg)) readLine() readLine() proc chat(facet: Facet; ds: Cap; username: string) = during(facet, ds, ?:Present) do (who: string): echo who, " joined" do: echo who, " left" onMessage(facet, ds, ?:Says) do (who: string, what: string): echo who, ": ", what discard publish(facet, ds, Present(username: username)) readStdin(facet, ds, username) proc main = let route = envRoute() var username = "" for kind, key, val in getopt(): if kind == cmdLongOption: case key of "user", "username": username = val if username == "": stderr.writeLine "--user: unspecified" else: runActor("chat") do (root: Facet): let ds = facet.newDataspace() facet.spawnRelays(ds) resolve(facet, ds, route) do (remote: Cap): chat(facet, remote, username) main()