143 lines
4.2 KiB
Scala
143 lines
4.2 KiB
Scala
package wow.doge.mygame.subsystems.moddingsystem
|
|
import java.io.FileNotFoundException
|
|
|
|
import scala.collection.View
|
|
import scala.collection.immutable.ArraySeq
|
|
import scala.util.Try
|
|
|
|
import cats.implicits._
|
|
import io.circe._
|
|
import io.circe.generic.semiauto._
|
|
import io.circe.parser._
|
|
import monix.bio.IO
|
|
import monix.bio.UIO
|
|
import java.nio.file.NoSuchFileException
|
|
import io.circe.generic.JsonCodec
|
|
|
|
@JsonCodec
|
|
final case class Test1(hello1: String, hello2: String)
|
|
@JsonCodec
|
|
final case class Test2(hello1: String)
|
|
final case class Plugin(name: String, priority: Int)
|
|
object Plugin {
|
|
implicit val pluginFormat: Decoder[Plugin] = deriveDecoder
|
|
}
|
|
|
|
object ModdingSystem {
|
|
sealed trait Error extends Serializable with Product
|
|
final case class CouldNotDecode(cause: String) extends Error
|
|
final case class ParseFailure(cause: String) extends Error
|
|
final case class FileNotFound(fileName: String) extends Error
|
|
case object GenericError extends Error
|
|
|
|
def readPluginsList(dir: os.Path): Try[Either[Error, ArraySeq[Plugin]]] =
|
|
Try(
|
|
parse(os.read(dir / "plugins.json"))
|
|
.map(
|
|
_.as[ArraySeq[Plugin]]
|
|
.leftMap(e => CouldNotDecode(e.getMessage()))
|
|
)
|
|
.leftMap((e: ParsingFailure) => ParseFailure(e.message))
|
|
.flatten
|
|
)
|
|
// .toValidated
|
|
|
|
def findPluginFiles(dir: os.Path): View[os.Path] =
|
|
os.list(dir)
|
|
.view
|
|
.filter(f => f.ext == "json" && f.baseName.endsWith("plugin"))
|
|
|
|
def findAndReadPluginFiles(
|
|
dir: os.Path,
|
|
plugins: ArraySeq[Plugin]
|
|
) =
|
|
plugins
|
|
.sortBy(_.priority)
|
|
.view
|
|
.map(p =>
|
|
p ->
|
|
Either
|
|
.catchNonFatal {
|
|
val path = dir / os.RelPath(p.name + ".plugin.json")
|
|
os.read(path)
|
|
}
|
|
.leftMap {
|
|
case _: FileNotFoundException =>
|
|
FileNotFound(p.name)
|
|
case _: NoSuchFileException => FileNotFound(p.name)
|
|
case e => GenericError
|
|
}
|
|
)
|
|
.partitionMap {
|
|
case (p, either) =>
|
|
either match {
|
|
case Left(value) => Left(p -> value)
|
|
case Right(value) => Right(p -> value)
|
|
}
|
|
}
|
|
|
|
def readPluginFiles(filePaths: View[os.Path]) = {
|
|
filePaths.map(path => os.read(path))
|
|
}
|
|
|
|
def parsePluginFiles(files: View[(Plugin, String)]) =
|
|
files
|
|
.map {
|
|
case (p, s) => p -> parse(s)
|
|
}
|
|
.partitionMap {
|
|
case (p, Left(value)) => Left(p -> value)
|
|
case (p, Right(value)) => Right(p -> value)
|
|
}
|
|
|
|
def mergePluginData(plugins: View[(Plugin, Json)]) = {
|
|
plugins.foldLeft(Json.fromString("empty")) {
|
|
case (json, that) =>
|
|
that match {
|
|
case (p, io.circe.Json.Null) => json //ignore null values
|
|
case (p, value) => json.deepMerge(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// def test =
|
|
// for {
|
|
// filePaths <- Task(findPluginFiles(os.pwd))
|
|
// files <- Task(readPluginFiles(filePaths))
|
|
// (failures, successes) <- Task(parsePluginFiles(files))
|
|
// merged <- Task(mergePluginData(successes))
|
|
// _ <- Task {
|
|
// println(s"Successes = ${successes.to(Seq)}")
|
|
// println(s"Failure = ${failures.to(Seq)}")
|
|
// println(s"Merged = $merged")
|
|
// }
|
|
// } yield ()
|
|
|
|
def test(wd: os.Path = os.pwd) =
|
|
for {
|
|
plugins <- IO.fromTryEither(readPluginsList(wd))
|
|
(readFailures, readSuccesses) <- UIO(findAndReadPluginFiles(wd, plugins))
|
|
(parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses))
|
|
res <- UIO(mergePluginData(parseSuccesses))
|
|
_ <- UIO {
|
|
println(s"Read Successes = ${readSuccesses.to(Seq)}")
|
|
println(s"Read Failures = ${readFailures.to(Seq)}")
|
|
println(s"Parse Successes = ${parseSuccesses.to(Seq)}")
|
|
println(s"Parse Failures = ${parseFailures.to(Seq)}")
|
|
println(s"Merged = $res")
|
|
}
|
|
} yield ()
|
|
|
|
// monix.eval.Task.deferAction(implicit s =>
|
|
// ModdingSystem
|
|
// .test()
|
|
// .leftMap(e => new Throwable(e.toString()))
|
|
// .to[monix.eval.Task]
|
|
// )
|
|
|
|
// def test3(wd: os.Path = os.pwd) = {
|
|
// (readPluginsList(os.pwd).toValidatedNec)
|
|
// }
|
|
;
|
|
}
|