Skip to content

Commit

Permalink
Merge pull request #10 from rcardin/9-deprecate-all-the-functions-wit…
Browse files Browse the repository at this point in the history
…hout-a-scope

Deprecated functions without a scope
  • Loading branch information
rcardin authored Apr 21, 2024
2 parents e11da9a + a892309 commit e27099d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 48 deletions.
35 changes: 22 additions & 13 deletions src/main/scala/in/rcard/raise4s/Builders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package in.rcard.raise4s

import scala.util.{Failure, Success, Try}

private[raise4s] def _either[Error, A](block: Raise[Error] ?=> A): Either[Error, A] = {
Raise.fold(block, error => Left(error), value => Right(value))
}

@deprecated("Use the Raise.either method instead", "0.0.3")
def either[A, Error](block: Raise[Error] ?=> A): Either[Error, A] =
fold(block, error => Left(error), value => Right(value))
_either(block)

object RaiseEitherPredef:
extension [Error, A](either: Either[Error, A])(using r: Raise[Error])
Expand All @@ -15,31 +20,35 @@ object RaiseOptionPredef:
extension [A](option: Option[A])(using optionRaise: Raise[None.type])
def bind(): A = option.getOrElse(Raise.raise(None))

def option[A](block: Raise[None.type] ?=> A): Option[A] =
fold(
{
given optionRaise: Raise[None.type] = new DefaultRaise() // ???
block(using optionRaise)
},
private[raise4s] def _option[A](block: Raise[None.type] ?=> A): Option[A] = {
Raise.fold(
block,
_ => None,
Some(_)
)
}

@deprecated("Use the Raise.option method instead", "0.0.3")
def option[A](block: Raise[None.type] ?=> A): Option[A] =
_option(block)

object RaiseTryPredef:
extension [A](tryValue: Try[A])(using tryRaise: Raise[Throwable])
def bind(): A = tryValue match
case Success(a) => a
case Failure(e) => tryRaise.raise(e)

def asTry[A](block: Raise[Throwable] ?=> A): Try[A] =
fold(
{
given tryRaise: Raise[Throwable] = new DefaultRaise()
block(using tryRaise)
},
private[raise4s] def _asTry[A](block: Raise[Throwable] ?=> A): Try[A] = {
Raise.fold(
block,
Failure(_),
Success(_)
)
}

@deprecated("Use the Raise.asTry method instead", "0.0.3")
def asTry[A](block: Raise[Throwable] ?=> A): Try[A] =
_asTry(block)

object RaiseAnyPredef:
extension [A](value: A) def succeed: Raise[Nothing] ?=> A = { value }
Expand Down
26 changes: 15 additions & 11 deletions src/main/scala/in/rcard/raise4s/Fold.scala
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
package in.rcard.raise4s

import scala.util.control.{ControlThrowable, NoStackTrace, NonFatal}
import scala.util.control.NonFatal

def fold[A, B, Error](
private[raise4s] def _fold[Error, B, A](
block: Raise[Error] ?=> A,
catchBlock: (throwable: Throwable) => B,
recover: (error: Error) => B,
transform: (value: A) => B
): B =
) = {
given raise: Raise[Error] = new DefaultRaise

try transform(block)
catch
case Raised(error) => recover(error.asInstanceOf[Error])
case NonFatal(e) => catchBlock(e)
case e: Throwable => throw e
}

//noinspection NoTailRecursionAnnotation
@deprecated("Use Raise.fold instead", "0.0.3")
def fold[A, B, Error](
block: Raise[Error] ?=> A,
catchBlock: (throwable: Throwable) => B,
recover: (error: Error) => B,
transform: (value: A) => B
): B = fold(block, ex => throw ex, recover, transform)
): B =
_fold(block, catchBlock, recover, transform)

//def runRaise[Error, A](block: Raise[Error] ?=> A): Error | A =
// given raise: Raise[Error] = new DefaultRaise
// try block(using raise)
// catch
// case Raised(error) => error.asInstanceOf[Error]
// case throwable: Throwable => throw throwable
@deprecated("Use Raise.fold instead", "0.0.3")
def fold[A, B, Error](
block: Raise[Error] ?=> A,
recover: (error: Error) => B,
transform: (value: A) => B
): B = _fold(block, ex => throw ex, recover, transform)
47 changes: 25 additions & 22 deletions src/main/scala/in/rcard/raise4s/Raise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ object Raise {
catchBlock: (throwable: Throwable) => B,
recover: (error: Error) => B,
transform: (value: A) => B
): B = in.rcard.raise4s.fold(block, catchBlock, recover, transform)
): B = _fold(block, catchBlock, recover, transform)

/** The most general way to execute a computation using [[Raise]]. Depending on the outcome of the
* `block`, one of the two continuations is run:
Expand Down Expand Up @@ -302,7 +302,7 @@ object Raise {
block: Raise[Error] ?=> A,
recover: (error: Error) => B,
transform: (value: A) => B
): B = in.rcard.raise4s.fold(block, recover, transform)
): B = _fold(block, ex => throw ex, recover, transform)

/** Runs a computation `block` using [[Raise]], and return its outcome as [[Either]].
* - [[Right]] represents success,
Expand Down Expand Up @@ -335,7 +335,7 @@ object Raise {
* @return
* An [[Either]] representing the outcome of the computation
*/
def either[A, Error](block: Raise[Error] ?=> A): Either[Error, A] = in.rcard.raise4s.either(block)
def either[A, Error](block: Raise[Error] ?=> A): Either[Error, A] = _either(block)

/** Runs a computation `block` using [[Raise]], and return its outcome as [[Option]].
* - [[Some]] represents success,
Expand All @@ -361,25 +361,28 @@ object Raise {
* @return
* An [[Option]] representing the outcome of the computation
*/
def option[A](block: Raise[None.type] ?=> A): Option[A] = in.rcard.raise4s.option(block)
def option[A](block: Raise[None.type] ?=> A): Option[A] = _option(block)

/** Runs a computation `block` using [[Raise]], and return its outcome as [[Try]].
*
* <h2>Example</h2>
* {{{
* val one: Try[Int] = Success(1)
* val failure: Try[Int] = Failure(new Exception("error"))
* val actual = asTry {
* val x = one.bind()
* val y = recover({ failure.bind() }, { _ => 1 })
* x + y
* }
* actual should be(Success(2))
* }}}
*
* @param block A computation that can raise errors of type `Throwable`
* @tparam A The type of the value returned by the computation
* @return An [[Try]] representing the outcome of the computation
*/
def asTry[A](block: Raise[Throwable] ?=> A): Try[A] = in.rcard.raise4s.asTry(block)
*
* <h2>Example</h2>
* {{{
* val one: Try[Int] = Success(1)
* val failure: Try[Int] = Failure(new Exception("error"))
* val actual = asTry {
* val x = one.bind()
* val y = recover({ failure.bind() }, { _ => 1 })
* x + y
* }
* actual should be(Success(2))
* }}}
*
* @param block
* A computation that can raise errors of type `Throwable`
* @tparam A
* The type of the value returned by the computation
* @return
* An [[Try]] representing the outcome of the computation
*/
def asTry[A](block: Raise[Throwable] ?=> A): Try[A] = _asTry(block)
}
4 changes: 2 additions & 2 deletions src/test/scala/in/rcard/raise4s/RaiseSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ class RaiseSpec extends AnyFlatSpec with Matchers {
}

"withError" should "return the value if it is not an error" in {
val actual = either {
val actual = Raise.either {
Raise.withError[Int, String, Int](s => s.length, { 42 })
}

actual should be(Right(42))
}

it should "return the transformed error if the value is an error" in {
val actual = either {
val actual = Raise.either {
Raise.withError[Int, String, Int](s => s.length, { Raise.raise("error") })
}

Expand Down

0 comments on commit e27099d

Please sign in to comment.