Skip to content

Commit

Permalink
dev: Add "all" refinement methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Iltotore committed Feb 12, 2024
1 parent c11a669 commit 3815159
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
26 changes: 26 additions & 0 deletions main/src/io/github/iltotore/iron/MapLogic.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.github.iltotore.iron

import scala.concurrent.Future

/**
* A typeclass providing a `map` method. Mainly used to abstract over Cats and ZIO Prelude.
*
* @tparam F the wrapper type
*/
trait MapLogic[F[_]]:

def map[A, B](wrapper: F[A], f: A => B): F[B]

object MapLogic:

given MapLogic[IterableOnce] with

def map[A, B](wrapper: IterableOnce[A], f: A => B): IterableOnce[B] = wrapper.iterator.map(f)

given [L]: MapLogic[[x] =>> Either[L, x]] with

override def map[A, B](wrapper: Either[L, A], f: A => B): Either[L, B] = wrapper.map(f)

given MapLogic[Future] with

override def map[A, B](wrapper: Future[A], f: A => B): Future[B] = wrapper.map(f)
36 changes: 34 additions & 2 deletions main/src/io/github/iltotore/iron/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import io.github.iltotore.iron.macros
import scala.Console.{CYAN, RESET}
import scala.compiletime.{codeOf, error, summonInline}
import scala.reflect.TypeTest
import scala.util.NotGiven
import scala.util.{boundary, NotGiven}
import scala.util.boundary.break

/**
* The main package of Iron. Contains:
Expand Down Expand Up @@ -107,4 +108,35 @@ extension [F[_], A](wrapper: F[A])
* @return constrained values, without performing constraint checks.
* @see [[assume]], [[autoRefine]], [[refineUnsafe]].
*/
inline def assumeAll[B]: F[A :| B] = wrapper
inline def assumeAll[B]: F[A :| B] = wrapper

/**
* Refine the given value(s) at runtime.
*
* @param constraint the constraint to test with the value to refine.
* @return the given values as [[IronType]].
* @throws an [[IllegalArgumentException]] if the constraint is not satisfied.
* @see [[refineUnsafe]].
*/
inline def refineAllUnsafe[B](using mapLogic: MapLogic[F], inline constraint: Constraint[A, B]): F[A :| B] =
mapLogic.map(wrapper, _.refineUnsafe[B])


inline def refineAllEither[B](using mapLogic: MapLogic[F], inline constraint: Constraint[A, B]): Either[String, F[A :| B]] =
boundary:
Right(mapLogic.map(
wrapper,
_.refineEither[B] match
case Right(value) => value
case Left(error) => break(Left(error))
))

inline def refineAllOption[B](using mapLogic: MapLogic[F], inline constraint: Constraint[A, B]): Option[F[A :| B]] =
boundary:
Some(mapLogic.map(
wrapper,
_.refineOption[B] match
case Some(value) => value
case None => break(None)
))

0 comments on commit 3815159

Please sign in to comment.