aboutsummaryrefslogtreecommitdiff
path: root/src/scalevalapokalypsi/utils/utils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/scalevalapokalypsi/utils/utils.scala')
-rw-r--r--src/scalevalapokalypsi/utils/utils.scala45
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
+