unison
unison copied to clipboard
rework some IO functions
I am proposing that we revamp the networking library as follows:
Rename builtin functions to be more discoverable:
In ucm, I tend to find funtions that operate on a type like socket by doing
"view Socket" to find out what namespace Socket
is in which would tell me
something like "lib.base.io.Socket" then I expect "ls lib.base.io.Socket" to
show me some functions that operate on Sockets
Old Name | New Name |
---|---|
io.socketReceive | io.Socket.receive |
io.socketSend | io.Socket.send |
io.socketClose | io.Socket.close |
io.socketPort | io.Socket.port |
io.getBuffering | io.Handle.getBuffering |
io.getBytes | io.Handle.getBytes |
io.getSomeBytes | io.Handle.getSomeBytes |
io.getLine | io.Handle.getLine |
io.handlePosition | io.Handle.position |
io.isFileEOF | io.Handle.isEof |
io.isFileOpen | io.Handle.isOpen |
io.isSeekable | io.Handle.isSeekable |
io.position | io.Handle.position |
io.putBytes | io.Handle.putBytes |
io.putText | io.Handle.putText |
io.StdHandle | io.Handle.Std |
io.stdHandle | io.Handle.std |
io.closeFile | io.Handle.close |
remove the Nat parameter from socketReceive
it's annoying now that the signatures of socketReceive and Tls.receive are different. We should just use 4096 in place of the nat paramater in the haskell implementation
Introduce new types to distinguish different states a Socket can be in
io.Socket.server: Optional HostName -> ServiceName -> Either Failure UnboundServerSocket
io.Socket.listen: UnboundServerSocket -> Either Failure BoundServerSocket
io.Socket.accept: BoundServerSocket -> Either Failure Socket
io.TlsSocket.newClient.impl: ClientConfig -> Socket -> Either Failure Tls
io.TlsSocket.newServer.impl: ServerConfig -> Socket -> Either Failure Tls
io.TlsSocket.handshake.impl: Tls -> Either Failure TlsSocket
Introduce a Connection ability so that generic code can be written that
sends and receives from sockets without caring if there the connection is Tls encrypted:
unique ability Connection where
send: Bytes: Either Failure ()
recieve: Either Failure Bytes
close: ()
Connection.tls: TlsSocket -> Request Connection a -> {Exception} a
Connection.tls sock = cases
{ send bs -> k } -> handle k (TlsSocket.send.impl sock bs) with tls sock
{ receive -> k } -> handle k (TlsSocket.receive.impl sock) with tls sock
{ close -> k } -> handle !k (TlsSocket.close sock) with tls sock
{ a } -> a
Connection.socket: TlsSocket -> Request Connection a -> {Exception} a
Connection.socket sock = cases
{ send bs -> k } -> handle k (Socket.send.impl sock bs) with socket sock
{ receive -> k } -> handle k (Socket.receive.impl sock) with socket sock
{ close -> k } -> handle !k (Socket.close sock) with socket sock
{ a } -> a
Connection.stream : '{Connection, Stream Bytes} ()
Connection.stream = do
Stream.emit Connection.read
!Connection.stream