All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.malliina.http4s.forms.scala Maven / Gradle / Ivy

package com.malliina.http4s

import com.malliina.http.{Errors, SingleError}
import com.malliina.values.{ErrorMessage, Readable}
import org.http4s.UrlForm

class FormReader(form: UrlForm):
  def read[T](key: String)(using fr: FormReadable[T]): Either[Errors, T] =
    FormReadable[T].read(key, form).left.map(err => Errors(SingleError.input(err.message)))

trait FormReadable[T]:
  def read(key: String, form: UrlForm): Either[ErrorMessage, T]

  def emap[U](f: T => Either[ErrorMessage, U]): FormReadable[U] = (key: String, form: UrlForm) =>
    read(key, form).flatMap(f)

object FormReadable:
  val string: FormReadable[String] = (key: String, form: UrlForm) =>
    form.getFirst(key).toRight(ErrorMessage(s"Not found: '$key'."))

  def apply[T](using fr: FormReadable[T]): FormReadable[T] = fr

  given option[T](using r: Readable[T]): FormReadable[Option[T]] =
    (key: String, form: UrlForm) =>
      form.getFirst(key).fold(Right(None))(s => r.read(s).map(Option.apply))

  given readable[T](using r: Readable[T]): FormReadable[T] =
    string.emap(str => r.read(str))

trait FormReadableT[T]:
  def read(url: UrlForm): Either[Errors, T]
  def map[U](f: T => U): FormReadableT[U] = emap(t => Right(f(t)))
  def emap[U](f: T => Either[Errors, U]): FormReadableT[U] =
    (form: UrlForm) =>
      read(form).flatMap: t =>
        f(t)
  def or[TT >: T](other: => FormReadableT[TT]): FormReadableT[TT] = form =>
    read(form).orElse(other.read(form))

object FormReadableT:
  def apply[T](using reader: FormReadableT[T]): FormReadableT[T] = reader
  given reader: FormReadableT[FormReader] = (urlForm: UrlForm) => Right(FormReader(urlForm))




© 2015 - 2024 Weber Informatics LLC | Privacy Policy