Skip to content

Commit

Permalink
Apply scalafmt
Browse files Browse the repository at this point in the history
  • Loading branch information
mdedetrich committed Feb 17, 2022
1 parent 7707199 commit 904795c
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 334 deletions.
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ThisBuild / name := "futiles"
ThisBuild / name := "futiles"
ThisBuild / organization := "com.markatta"

ThisBuild / crossScalaVersions := Seq("2.12.15", "2.11.12", "2.13.8")
ThisBuild / scalaVersion := crossScalaVersions.value.last
ThisBuild / scalaVersion := crossScalaVersions.value.last
ThisBuild / scalacOptions ++= Seq("-feature", "-deprecation", "-Xfatal-warnings", "-Xlint")

libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.0.8" % "test")
Expand All @@ -14,8 +14,8 @@ licenses := Seq(
"http://www.apache.org/licenses/LICENSE-2.0"
)
)
homepage := Some(url("https://github.com/johanandren/futiles"))
publishMavenStyle := true
homepage := Some(url("https://github.com/johanandren/futiles"))
publishMavenStyle := true
Test / publishArtifact := false
pomIncludeRepository := { _ =>
false
Expand Down
8 changes: 3 additions & 5 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.0")

addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.14.2")

addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.0")
addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.14.2")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
50 changes: 24 additions & 26 deletions src/main/scala-2.13/markatta/futiles/Sequencing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,59 +20,57 @@ import scala.collection.BuildFrom
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

/**
* Functions for transforming something with a future inside into a future with something inside
/** Functions for transforming something with a future inside into a future with something inside
*/
object Sequencing {

/**
* Turn an option of a future inside out, much like Future.sequence but keep it an Option
/** Turn an option of a future inside out, much like Future.sequence but keep it an Option
*/
def sequenceOpt[A](f: Option[Future[A]]): Future[Option[A]] =
f.map(_.map(Some(_))(CallingThreadExecutionContext))
.getOrElse(Future.successful(None))

/**
* @return a Future(Left(l)) for a Left(Future(l)) and a Future(Right(r)) for a Right(Future(r))
/** @return
* a Future(Left(l)) for a Left(Future(l)) and a Future(Right(r)) for a Right(Future(r))
*/
def sequenceEither[L, R](
either: Either[Future[L], Future[R]]
either: Either[Future[L], Future[R]]
): Future[Either[L, R]] =
either.fold(
lf => lf.map(l => Left[L, R](l))(CallingThreadExecutionContext),
rf => rf.map(r => Right[L, R](r))(CallingThreadExecutionContext)
)

/**
* @return a Future(Left(l)) for a Left(Future(l)) and a Future(Right(r)) for a Right(r)
/** @return
* a Future(Left(l)) for a Left(Future(l)) and a Future(Right(r)) for a Right(r)
*/
def sequenceL[L, R](either: Either[Future[L], R]): Future[Either[L, R]] =
sequenceEither(either.map(Future.successful))

/**
* @return a Future(Left(l)) for a Left(l) and a Future(Right(r)) for a Right(Future(r))
/** @return
* a Future(Left(l)) for a Left(l) and a Future(Right(r)) for a Right(Future(r))
*/
def sequenceR[L, R](either: Either[L, Future[R]]): Future[Either[L, R]] =
sequenceEither(either.left.map(Future.successful))

/**
* Like Future.sequence() but instead of failing the result future when one future fails
* it will collect each success or failure and complete once all futures has either failed or succeeded
/** Like Future.sequence() but instead of failing the result future when one future fails it will collect each success
* or failure and complete once all futures has either failed or succeeded
*
* @return A future that completes once all the given futures has completed, successfully or failed, so
* that all of the failures can be handled, reported etc.
* @see Lifting.liftTry()
* @return
* A future that completes once all the given futures has completed, successfully or failed, so that all of the
* failures can be handled, reported etc.
* @see
* Lifting.liftTry()
*/
def sequenceTries[A, M[X] <: IterableOnce[X]](fas: M[Future[A]])(
implicit ec: ExecutionContext,
cbf: BuildFrom[M[Future[A]], Try[A], M[Try[A]]]
def sequenceTries[A, M[X] <: IterableOnce[X]](fas: M[Future[A]])(implicit
ec: ExecutionContext,
cbf: BuildFrom[M[Future[A]], Try[A], M[Try[A]]]
): Future[M[Try[A]]] = {
val fts = fas.iterator.foldLeft(Future.successful(cbf.newBuilder(fas))) {
(facc, fa) =>
for {
acc <- facc
ta <- Lifting.liftTry(fa)
} yield acc += ta
val fts = fas.iterator.foldLeft(Future.successful(cbf.newBuilder(fas))) { (facc, fa) =>
for {
acc <- facc
ta <- Lifting.liftTry(fa)
} yield acc += ta
}
fts.map(_.result())
}
Expand Down
34 changes: 16 additions & 18 deletions src/main/scala-2.13/markatta/futiles/Traversal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,33 @@ package markatta.futiles
import scala.collection.BuildFrom
import scala.concurrent.{ExecutionContext, Future}

/**
* Utilities that complement scala.concurrent.Future.traverse, working with creating a future out of each element
* in a collection and collecting those into a single future.
/** Utilities that complement scala.concurrent.Future.traverse, working with creating a future out of each element in a
* collection and collecting those into a single future.
*/
object Traversal {

/**
* For each ```A``` apply the function ```f```, and wait for it to complete before continuing with the next ```A```
/** For each ```A``` apply the function ```f```, and wait for it to complete before continuing with the next ```A```
*
* @return The future all ```A```s turned into ```B``` or the first failure that occurred
* @return
* The future all ```A```s turned into ```B``` or the first failure that occurred
*/
def traverseSequentially[A, B, M[X] <: IterableOnce[X]](
as: M[A]
)(f: A => Future[B])(implicit ec: ExecutionContext,
cbf: BuildFrom[M[A], B, M[B]]): Future[M[B]] =
foldLeftSequentially(as.iterator.to(Iterable))(cbf.newBuilder(as))(
(builder, a) => f(a).map(b => builder += b)
).map(_.result())
as: M[A]
)(f: A => Future[B])(implicit ec: ExecutionContext, cbf: BuildFrom[M[A], B, M[B]]): Future[M[B]] =
foldLeftSequentially(as.iterator.to(Iterable))(cbf.newBuilder(as))((builder, a) => f(a).map(b => builder += b))
.map(_.result())

/**
* Like a regular fold left, but with an operation that returns futures, each future will complete before the next
/** Like a regular fold left, but with an operation that returns futures, each future will complete before the next
* element in ```as``` is executed.
*
* @param z The zero value, if ```as``` is empty, this is returned, if not this is fed into ```f``` as the ```B``` value
* @return The future of all ```A``` folded into ```B```s, or a future that is failed with any exception that is thrown
* from f
* @param z
* The zero value, if ```as``` is empty, this is returned, if not this is fed into ```f``` as the ```B``` value
* @return
* The future of all ```A``` folded into ```B```s, or a future that is failed with any exception that is thrown
* from f
*/
def foldLeftSequentially[A, B](
as: Iterable[A]
as: Iterable[A]
)(z: B)(f: (B, A) => Future[B])(implicit ec: ExecutionContext): Future[B] =
if (as.isEmpty) Future.successful(z)
else f(z, as.head).flatMap(b => foldLeftSequentially(as.tail)(b)(f))
Expand Down
41 changes: 20 additions & 21 deletions src/main/scala/markatta/futiles/Boolean.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,23 @@ package markatta.futiles

import scala.concurrent.{ExecutionContext, Future}

/**
* Boolean algebra composition operations for Future[Boolean]
*
* Credit goes to http://stackoverflow.com/users/3235823/dwickern for the idea to do this.
*/
/** Boolean algebra composition operations for Future[Boolean]
*
* Credit goes to http://stackoverflow.com/users/3235823/dwickern for the idea to do this.
*/
object Boolean {

/**
* @return A new future that will be true if both futures are true, if this one
* is false the second one will not be evaluated (just like with regular booleans).
*/
/** @return
* A new future that will be true if both futures are true, if this one is false the second one will not be
* evaluated (just like with regular booleans).
*/
def and(fb: Future[Boolean], other: => Future[Boolean])(implicit ec: ExecutionContext) =
fb.flatMap(b => if (!b) Future.successful(false) else other)

/**
* @return A new future that will be true if either future is true, if this one
* is true the second one will not be evaluated (just like with regular booleans).
*/
/** @return
* A new future that will be true if either future is true, if this one is true the second one will not be
* evaluated (just like with regular booleans).
*/
def or(fb: Future[Boolean], other: => Future[Boolean])(implicit ec: ExecutionContext) =
fb.flatMap(b => if (b) Future.successful(true) else other)

Expand All @@ -46,17 +45,17 @@ object Boolean {

implicit class FutureBooleanDecorator(val fb: Future[Boolean]) extends AnyVal {

/**
* @return A new future that will be true if both futures are true, if this one
* is false the second one will not be evaluated (just like with regular booleans).
*/
/** @return
* A new future that will be true if both futures are true, if this one is false the second one will not be
* evaluated (just like with regular booleans).
*/
def &&(other: => Future[Boolean])(implicit ec: ExecutionContext) =
and(fb, other)(ec)

/**
* @return A new future that will be true if either future is true, if this one
* is true the second one will not be evaluated (just like with regular booleans).
*/
/** @return
* A new future that will be true if either future is true, if this one is true the second one will not be
* evaluated (just like with regular booleans).
*/
def ||(other: => Future[Boolean])(implicit ec: ExecutionContext) =
or(fb, other)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ package markatta.futiles

import scala.concurrent.ExecutionContext

/**
* This is a common optimization that allows us to avoid scheduling future transformations
* for execution on the execution context but instead just run them on the calling thread.
* Should never be used for anything but simple quick transformations.
*/
/** This is a common optimization that allows us to avoid scheduling future transformations for execution on the
* execution context but instead just run them on the calling thread. Should never be used for anything but simple
* quick transformations.
*/
private[futiles] object CallingThreadExecutionContext extends ExecutionContext {
override def execute(runnable: Runnable): Unit = runnable.run()
override def execute(runnable: Runnable): Unit = runnable.run()
override def reportFailure(cause: Throwable): Unit = throw cause
implicit def Implicit: ExecutionContext = this
implicit def Implicit: ExecutionContext = this
}
Loading

0 comments on commit 904795c

Please sign in to comment.