io.hireproof.structure.Headers.scala Maven / Gradle / Ivy
The newest version!
package io.hireproof.structure
import cats.Invariant
import cats.data.{Chain, Validated}
import cats.syntax.all._
import io.hireproof.screening.Validation
import org.typelevel.ci._
sealed abstract class Headers[A] extends Structure.Product[A] { self =>
final override type Self[a] = Headers[a]
final override type Element[a] = Header[a]
final override type Group[a] = Headers[a]
def toChain: Chain[Header[_]]
final override def zipAll[T](headers: Headers[T]): Headers[A |*| T] = new Headers[A |*| T] {
override def toChain: Chain[Header[_]] = self.toChain ++ headers.toChain
override def fromStringChain(
values: Chain[(CIString, String)]
): Validated[Errors, (Chain[(CIString, String)], A |*| T)] = self
.fromStringChain(values)
.andThen { case (remainders, a) => headers.fromStringChain(remainders).map(_.tupleLeft(a)) }
override def toStringChain(at: A |*| T): Chain[(CIString, String)] =
self.toStringChain(at._1) ++ headers.toStringChain(at._2)
}
final def zip[T](header: Header[T]): Headers[A |*| T] = zipAll(Headers.fromHeader(header))
override private[structure] def vimap[T](
f: A => Validated[Errors, T],
g: T => A,
validation: Option[Validation[_, _]]
): Headers[T] = new Headers[T] {
override def toChain: Chain[Header[_]] = self.toChain
override def fromStringChain(
headers: Chain[(CIString, String)]
): Validated[Errors, (Chain[(CIString, String)], T)] = self.fromStringChain(headers).andThen(_.traverse(f(_)))
override def toStringChain(t: T): Chain[(CIString, String)] = self.toStringChain(g(t))
}
def fromStringChain(headers: Chain[(CIString, String)]): Validated[Errors, (Chain[(CIString, String)], A)]
def toStringChain(a: A): Chain[(CIString, String)]
}
object Headers {
val Empty: Headers[Unit] = new Headers[Unit] {
override def toChain: Chain[Header[_]] = Chain.empty
override def fromStringChain(
headers: Chain[(CIString, String)]
): Validated[Errors, (Chain[(CIString, String)], Unit)] =
(headers, ()).valid
override def toStringChain(a: Unit): Chain[(CIString, String)] = Chain.empty
}
def fromHeader[A](header: Header[A]): Headers[A] = new Headers[A] {
override def toChain: Chain[Header[_]] = Chain.one(header)
override def fromStringChain(
headers: Chain[(CIString, String)]
): Validated[Errors, (Chain[(CIString, String)], A)] = header.fromStringChain(headers)
override def toStringChain(a: A): Chain[(CIString, String)] = header.toStringChain(a)
}
implicit val invariant: Invariant[Headers] = new Invariant[Headers] {
override def imap[A, B](fa: Headers[A])(f: A => B)(g: B => A): Headers[B] = fa.imap(f)(g)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy