package fs2chat package client import cats.effect.{Blocker, ExitCode, IO, IOApp} import cats.implicits._ import com.comcast.ip4s._ import com.monovore.decline._ import fs2.io.tcp.SocketGroup object ClientApp extends IOApp { private val argsParser: Command[(Username, SocketAddress[IpAddress])] = Command("fs2chat-client", "FS2 Chat Client") { ( Opts .option[String]("username", "Desired username", "u") .map(Username.apply), Opts .option[String]("address", "Address of chat server") .withDefault("127.0.0.1") .mapValidated(p => IpAddress(p).toValidNel("Invalid IP address")), Opts .option[Int]("port", "Port of chat server") .withDefault(5555) .mapValidated(p => Port(p).toValidNel("Invalid port number")) ).mapN { case (desiredUsername, ip, port) => desiredUsername -> SocketAddress(ip, port) } } def run(args: List[String]): IO[ExitCode] = argsParser.parse(args) match { case Left(help) => IO(System.err.println(help)).as(ExitCode.Error) case Right((desiredUsername, address)) => Blocker[IO] .use { blocker => Console[IO](blocker).flatMap { console => SocketGroup[IO](blocker).use { socketGroup => Client .start[IO](console, socketGroup, address, desiredUsername) .compile .drain } } } .as(ExitCode.Success) } }