Skip to content

Instantly share code, notes, and snippets.

@olafurpg
Last active June 23, 2020 08:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olafurpg/ac4f86d8d6e09e312e035217ca9e185a to your computer and use it in GitHub Desktop.
Save olafurpg/ac4f86d8d6e09e312e035217ca9e185a to your computer and use it in GitHub Desktop.
import mopt.internal.diagnostics.WithFilterDiagnostic
final case class ValueResult[+A](value: A) extends DecodingResult[A]
final case class ErrorResult(error: Diagnostic) extends DecodingResult[Nothing]
sealed abstract class DecodingResult[+A] extends Product with Serializable {
def get: A =
fold(identity, throw new NoSuchElementException())
def getOrElse[B >: A](other: => B): B =
fold(identity, _ => other)
def orElse[B >: A](other: => DecodingResult[B]): DecodingResult[B] =
fold(ValueResult(_), _ => other)
def toOption: Option[A] =
fold(Some(_), _ => None)
def toEither: Either[Diagnostic, A] =
fold(Right(_), Left(_))
def toList: List[A] =
fold(List(_), _ => List())
def iterator(): Iterator[A] =
fold(Iterator(_), _ => Iterator())
def foreach[B](fn: A => B): Unit =
fold(a => fn(a), _ => ())
def map[B](fn: A => B): DecodingResult[B] =
fold(a => ValueResult(fn(a)), ErrorResult(_))
def flatMap[B](fn: A => DecodingResult[B]): DecodingResult[B] =
fold(a => fn(a), ErrorResult(_))
def filter(fn: A => Boolean): DecodingResult[A] =
withFilter(fn)
def withFilter(fn: A => Boolean): DecodingResult[A] =
fold(
a => {
if (fn(a)) ValueResult(a)
else ErrorResult(new WithFilterDiagnostic(a, fn))
},
ErrorResult(_)
)
def fold[B](onValue: A => B, onError: Diagnostic => B): B =
this match {
case ValueResult(value) => onValue(value)
case ErrorResult(error) => onError(error)
}
def product[B](other: DecodingResult[B]): DecodingResult[(A, B)] =
(this, other) match {
case (ErrorResult(a), ErrorResult(b)) => ErrorResult(a.mergeWith(b))
case (ErrorResult(a), _) => ErrorResult(a)
case (_, ErrorResult(b)) => ErrorResult(b)
case (ValueResult(a), ValueResult(b)) => ValueResult((a, b))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment