// socket.wren foreign class Socket { // Asynchronous static methods that perform raw socket operations. // These are the direct bindings to the C backend. foreign static connect_(host, port, callback) foreign static new_(callback) foreign static bind_(sock, host, port, callback) foreign static listen_(sock, backlog, callback) foreign static accept_(sock, callback) foreign static read_(sock, length, callback) foreign static write_(sock, data, callback) // Additional raw functions can be added here following the pattern. } class SocketInstance { construct new(socketFd) { _sock = socketFd } // Instance methods providing a more convenient API. accept() { var fiber = Fiber.current Socket.accept_(_sock) { |err, newSock| fiber.transfer([err, newSock]) } return Fiber.yield() } read(length) { var fiber = Fiber.current Socket.read_(_sock, length) { |err, data| fiber.transfer([err, data]) } return Fiber.yield() } write(data) { var fiber = Fiber.current Socket.write_(_sock, data) { |err, nothing| fiber.transfer(err) } return Fiber.yield() } // Static methods for creating client and server sockets. static connect(host, port) { var fiber = Fiber.current Socket.connect_(host, port) { |err, sock| if (err) { fiber.transfer([err, null]) } else { fiber.transfer([null, SocketInstance.new(sock)]) } } return Fiber.yield() } static new() { var fiber = Fiber.current Socket.new_() { |err, sock| if (err) { fiber.transfer([err, null]) } else { fiber.transfer([null, SocketInstance.new(sock)]) } } return Fiber.yield() } bind(host, port) { var fiber = Fiber.current Socket.bind_(_sock, host, port) { |err, success| fiber.transfer([err, success]) } return Fiber.yield() } listen(backlog) { var fiber = Fiber.current Socket.listen_(_sock, backlog) { |err, success| fiber.transfer([err, success]) } return Fiber.yield() } }