Refactor occurrences folding streams of strings

This commit is contained in:
eikek
2021-09-23 14:53:42 +02:00
parent 071f4067bf
commit 40727d205a
2 changed files with 14 additions and 29 deletions

View File

@ -14,24 +14,14 @@ import io.circe._
import io.circe.parser._ import io.circe.parser._
trait StreamSyntax { trait StreamSyntax {
implicit class StringStreamOps[F[_]](s: Stream[F, String]) { implicit class StringStreamOps[F[_]](s: Stream[F, String]) {
def parseJsonAs[A](implicit d: Decoder[A], F: Sync[F]): F[Either[Throwable, A]] = def parseJsonAs[A](implicit d: Decoder[A], F: Sync[F]): F[Either[Throwable, A]] =
s.fold("")(_ + _) s.compile.string
.compile .map(str =>
.last
.map(optStr =>
for { for {
str <-
optStr
.map(_.trim)
.toRight(new Exception("Empty string cannot be parsed into a value"))
json <- parse(str).leftMap(_.underlying) json <- parse(str).leftMap(_.underlying)
value <- json.as[A] value <- json.as[A]
} yield value } yield value
) )
} }
} }

View File

@ -11,7 +11,7 @@ import java.util.concurrent.atomic.AtomicReference
import cats.effect._ import cats.effect._
import cats.implicits._ import cats.implicits._
import fs2.{Stream, text} import fs2.text
import docspell.restserver.{BuildInfo, Config} import docspell.restserver.{BuildInfo, Config}
@ -20,6 +20,7 @@ import org.http4s.HttpRoutes
import org.http4s._ import org.http4s._
import org.http4s.dsl.Http4sDsl import org.http4s.dsl.Http4sDsl
import org.http4s.headers._ import org.http4s.headers._
import org.http4s.implicits._
import org.log4s._ import org.log4s._
import yamusca.implicits._ import yamusca.implicits._
import yamusca.imports._ import yamusca.imports._
@ -27,8 +28,8 @@ import yamusca.imports._
object TemplateRoutes { object TemplateRoutes {
private[this] val logger = getLogger private[this] val logger = getLogger
val `text/html` = new MediaType("text", "html") private val textHtml = mediaType"text/html"
val `application/javascript` = new MediaType("application", "javascript") private val appJavascript = mediaType"application/javascript"
trait InnerRoutes[F[_]] { trait InnerRoutes[F[_]] {
def doc: HttpRoutes[F] def doc: HttpRoutes[F]
@ -52,7 +53,7 @@ object TemplateRoutes {
templ <- docTemplate templ <- docTemplate
resp <- Ok( resp <- Ok(
DocData().render(templ), DocData().render(templ),
`Content-Type`(`text/html`, Charset.`UTF-8`) `Content-Type`(textHtml, Charset.`UTF-8`)
) )
} yield resp } yield resp
} }
@ -62,7 +63,7 @@ object TemplateRoutes {
templ <- indexTemplate templ <- indexTemplate
resp <- Ok( resp <- Ok(
IndexData(cfg).render(templ), IndexData(cfg).render(templ),
`Content-Type`(`text/html`, Charset.`UTF-8`) `Content-Type`(textHtml, Charset.`UTF-8`)
) )
} yield resp } yield resp
} }
@ -73,7 +74,7 @@ object TemplateRoutes {
templ <- swTemplate templ <- swTemplate
resp <- Ok( resp <- Ok(
IndexData(cfg).render(templ), IndexData(cfg).render(templ),
`Content-Type`(`application/javascript`, Charset.`UTF-8`) `Content-Type`(appJavascript, Charset.`UTF-8`)
) )
} yield resp } yield resp
} }
@ -89,23 +90,17 @@ object TemplateRoutes {
} }
def loadUrl[F[_]: Sync](url: URL): F[String] = def loadUrl[F[_]: Sync](url: URL): F[String] =
Stream fs2.io
.bracket(Sync[F].delay(url.openStream))(in => Sync[F].delay(in.close())) .readInputStream(Sync[F].delay(url.openStream()), 64 * 1024)
.flatMap(in => fs2.io.readInputStream(in.pure[F], 64 * 1024, false))
.through(text.utf8.decode) .through(text.utf8.decode)
.compile .compile
.fold("")(_ + _) .string
def parseTemplate[F[_]: Sync](str: String): F[Template] = def parseTemplate[F[_]: Sync](str: String): F[Template] =
Sync[F].delay { Sync[F].pure(mustache.parse(str).leftMap(err => new Exception(err._2))).rethrow
mustache.parse(str) match {
case Right(t) => t
case Left((_, err)) => sys.error(err)
}
}
def loadTemplate[F[_]: Sync](url: URL): F[Template] = def loadTemplate[F[_]: Sync](url: URL): F[Template] =
loadUrl[F](url).flatMap(s => parseTemplate(s)).map { t => loadUrl[F](url).flatMap(parseTemplate[F]).map { t =>
logger.info(s"Compiled template $url") logger.info(s"Compiled template $url")
t t
} }