From fcd61145534857fe28f3a1fc288921646007ad20 Mon Sep 17 00:00:00 2001 From: Jules Ivanic Date: Mon, 13 Aug 2018 16:18:56 +0200 Subject: [PATCH] [WIP] Add `Task.fromEither` functions (#694) * Add `Task.fromEither` methods * implement tests for `Task.fromEither` functions --- .../src/main/scala/monix/eval/Task.scala | 14 +++ .../monix/eval/TaskFromEitherSuite.scala | 100 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 monix-eval/shared/src/test/scala/monix/eval/TaskFromEitherSuite.scala diff --git a/monix-eval/shared/src/main/scala/monix/eval/Task.scala b/monix-eval/shared/src/main/scala/monix/eval/Task.scala index 9f05ecce4..18b533ed0 100644 --- a/monix-eval/shared/src/main/scala/monix/eval/Task.scala +++ b/monix-eval/shared/src/main/scala/monix/eval/Task.scala @@ -2185,6 +2185,20 @@ object Task extends TaskInstancesLevel1 { case Failure(ex) => Error(ex) } + /** Builds a [[Task]] instance out of a Scala `Either`. */ + def fromEither[E <: Throwable, A](a: Either[E, A]): Task[A] = + a match { + case Right(v) => Now(v) + case Left(ex) => Error(ex) + } + + /** Builds a [[Task]] instance out of a Scala `Either`. */ + def fromEither[E, A](f: E => Throwable)(a: Either[E, A]): Task[A] = + a match { + case Right(v) => Now(v) + case Left(ex) => Error(f(ex)) + } + /** Keeps calling `f` until it returns a `Right` result. * * Based on Phil Freeman's diff --git a/monix-eval/shared/src/test/scala/monix/eval/TaskFromEitherSuite.scala b/monix-eval/shared/src/test/scala/monix/eval/TaskFromEitherSuite.scala new file mode 100644 index 000000000..4e2f3e9b0 --- /dev/null +++ b/monix-eval/shared/src/test/scala/monix/eval/TaskFromEitherSuite.scala @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014-2018 by The Monix Project Developers. + * See the project homepage at: https://monix.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package monix.eval + +import monix.eval.Task.{Error, Now} +import monix.execution.exceptions.DummyException +import monix.execution.internal.Platform + +import scala.util.{Failure, Success} + +object TaskFromEitherSuite extends BaseTestSuite { + test("Task.fromEither (`E <: Throwable` version) should returns a Now with a Right") { implicit s => + val t = Task.fromEither(Right(10)) + assert(t.isInstanceOf[Now[_]]) + } + + test("Task.fromEither (`E <: Throwable` version) should succeed with a Right") { implicit s => + val t = Task.fromEither(Right(10)) + val f = t.runAsync + assertEquals(f.value, Some(Success(10))) + } + + test("Task.fromEither (`E <: Throwable` version) should returns an Error with a Left") { implicit s => + val dummy = DummyException("dummy") + val t = Task.fromEither(Left(dummy)) + assert(t.isInstanceOf[Error[_]]) + } + + test("Task.fromEither (`E <: Throwable` version) should fail with a Left") { implicit s => + val dummy = DummyException("dummy") + val t = Task.fromEither(Left(dummy)) + val f = t.runAsync + assertEquals(f.value, Some(Failure(dummy))) + } + + test("Task.fromEither (`E <: Throwable` version) with a Right should be stack safe") { implicit s => + val count = if (Platform.isJVM) 100000 else 5000 + var result = Task.fromEither(Right(1)).runAsync + for (_ <- 0 until count) result = Task.fromEither(Right(1)).runAsync + assertEquals(result.value, Some(Success(1))) + } + + test("Task.fromEither (`E <: Throwable` version) with a Left should be stack safe") { implicit s => + val count = if (Platform.isJVM) 100000 else 5000 + var result = Task.fromEither(Left(DummyException("dummy"))).runAsync + for (_ <- 0 until count) result = Task.fromEither(Left(DummyException("dummy"))).runAsync + assertEquals(result.value, Some(Failure(DummyException("dummy")))) + } + + test("Task.fromEither (free `E` version) should returns a Now with a Right") { implicit s => + val t = Task.fromEither(DummyException)(Right(10)) + assert(t.isInstanceOf[Now[_]]) + } + + test("Task.fromEither (free `E` version) should succeed with a Right") { implicit s => + val t = Task.fromEither(DummyException)(Right(10)) + val f = t.runAsync + assertEquals(f.value, Some(Success(10))) + } + + test("Task.fromEither (free `E` version) should returns an Error with a Left") { implicit s => + val t = Task.fromEither(DummyException)(Left("dummy")) + assert(t.isInstanceOf[Error[_]]) + } + + test("Task.fromEither (free `E` version) should fail with a Left") { implicit s => + val t = Task.fromEither(DummyException)(Left("dummy")) + val f = t.runAsync + assertEquals(f.value, Some(Failure(DummyException("dummy")))) + } + + test("Task.fromEither (free `E` version) with a Right should be stack safe") { implicit s => + val count = if (Platform.isJVM) 100000 else 5000 + var result = Task.fromEither(DummyException)(Right(1)).runAsync + for (_ <- 0 until count) result = Task.fromEither(DummyException)(Right(1)).runAsync + assertEquals(result.value, Some(Success(1))) + } + + test("Task.fromEither (free `E` version) with a Left should be stack safe") { implicit s => + val count = if (Platform.isJVM) 100000 else 5000 + var result = Task.fromEither(DummyException)(Left("dummy")).runAsync + for (_ <- 0 until count) result = Task.fromEither(DummyException)(Left("dummy")).runAsync + assertEquals(result.value, Some(Failure(DummyException("dummy")))) + } +}