Skip to content

Instantly share code, notes, and snippets.

@nightscape
Created January 17, 2020 12:55
Show Gist options
  • Save nightscape/0aa630886069d03d5272bfd6539c26ed to your computer and use it in GitHub Desktop.
Save nightscape/0aa630886069d03d5272bfd6539c26ed to your computer and use it in GitHub Desktop.
case class MapIncluding[K](keys: Seq[K], optionally: Seq[K] = Seq()) {
def unapply[V](m: Map[K, V]): Option[(Seq[V], Seq[Option[V]])] =
if (keys.forall(m.contains)) {
Some((keys.map(m), optionally.map(m.get)))
} else {
None
}
}
sealed trait MapRequirements[K] {
type ResultType[V]
def unapplySeq[V](m: Map[K, V]): Option[ResultType[V]]
}
case class RequiredKeys[K](keys: K*) extends MapRequirements[K] {
type ResultType[V] = Seq[V]
def unapplySeq[V](m: Map[K, V]): Option[Seq[V]] =
if (keys.forall(m.contains)) {
Some(keys.map(m))
} else {
None
}
}
case class OptionalKeys[K](keys: K*) extends MapRequirements[K] {
type ResultType[V] = Seq[Option[V]]
def unapplySeq[V](m: Map[K, V]): Option[Seq[Option[V]]] = Some(keys.map(m.get))
}
case class MapWith[K](
requiredKeys: RequiredKeys[K] = RequiredKeys[K](),
optionalKeys: OptionalKeys[K] = OptionalKeys[K]()
) {
def unapply[V](m: Map[K, V]): Option[(requiredKeys.ResultType[V], optionalKeys.ResultType[V])] =
for {
req <- requiredKeys.unapplySeq(m)
opt <- optionalKeys.unapplySeq(m)
} yield (req, opt)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment