diff options
Diffstat (limited to 'src/scalevalapokalypsi/utils/utils.scala')
-rw-r--r-- | src/scalevalapokalypsi/utils/utils.scala | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/src/scalevalapokalypsi/utils/utils.scala b/src/scalevalapokalypsi/utils/utils.scala index ab262ad..54d407b 100644 --- a/src/scalevalapokalypsi/utils/utils.scala +++ b/src/scalevalapokalypsi/utils/utils.scala @@ -2,6 +2,9 @@ package scalevalapokalypsi.utils import java.io.InputStream import java.nio.charset.StandardCharsets +import scala.util.Try +import scalevalapokalypsi.constants.* +import scala.io.StdIn.readLine /** Converts this string to an array of bytes (probably for transmission). * @@ -11,6 +14,16 @@ import java.nio.charset.StandardCharsets def stringToByteArray(str: String): Array[Byte] = str.getBytes(StandardCharsets.UTF_8) +/** Converts the given byte array to a string if possible*. + * (* Doesn't convert strings with control sequences in them) + * + * @param bytes the byte array to convert + * @return the matching string, if possible*. + */ +def byteArrayToString(bytes: Array[Byte]): Option[String] = + Try(String(bytes, StandardCharsets.UTF_8)) + .toOption + /** Reads n characters from the given InputStream blockingly. * * @param input the InputStream to read from @@ -25,5 +38,33 @@ def getNCharsFromSocket(input: InputStream, n: Int): Option[String] = val res = input.read(buffer, i, n - i) if res < 0 then failed = true i += res - // TODO: better error handling - if failed then None else Some(String(buffer, StandardCharsets.UTF_8)) + if failed then None else byteArrayToString(buffer) + +def isPrintable(s: String): Boolean = + FORBIDDEN_CHARACTERS.forall((c: Char) => !(s contains c)) + + +/** Gets input from STDIN until the line entered is appoved + * by a validator function. + * + * @param message A query to represent the user with when requesting input + * @param validator A validator function. Should return Right[A] when the + * input is valid and Left[String] when the input is invalid, + * where the string will be printed to the user to notify + * their input was invalid. + * @return The first encountered valid string, see `validator`. + */ +def getValidInput[A]( + message: String, + validator: String => Either[String, A] +): A = + LazyList.continually(readLine(s"$message\n> ")) + .flatMap(input => + validator(input) match + case Left(s) => + println(s) + None + case Right(a) => + Some(a) + ).head + |