Skip to content

Commit

Permalink
Add Output.when helper method (#439)
Browse files Browse the repository at this point in the history
fixes #435
  • Loading branch information
pawelprazak authored Apr 9, 2024
1 parent 94ba35f commit f4ba7cc
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
24 changes: 24 additions & 0 deletions core/src/main/scala/besom/internal/Output.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ trait OutputFactory:
)(using BuildFrom[CC[Output[B]], B, To], Context): Output[To] = sequence(coll.map(f).asInstanceOf[CC[Output[B]]])

def fail(t: Throwable)(using Context): Output[Nothing] = Output.fail(t)

def when[A: Typeable](cond: => Input.Optional[Boolean])(a: => Input.Optional[A])(using ctx: Context): Output[Option[A]] =
Output.when(cond)(a)

end OutputFactory

trait OutputExtensionsFactory:
Expand Down Expand Up @@ -188,4 +192,24 @@ object Output:
def secret[A](value: A)(using ctx: Context): Output[A] =
new Output[A](ctx.registerTask(Result.pure(OutputData(value, Set.empty, isSecret = true))))

def when[A: Typeable](cond: => Input.Optional[Boolean])(
a: => Input.Optional[A]
)(using ctx: Context): Output[Option[A]] =
val p: Output[Boolean] = cond.asOptionOutput(isSecret = false).flatMap {
case None => Output(false)
case Some(b: Boolean) => Output(b)
}

def f(c: Boolean): Output[Option[A]] =
a.asOptionOutput(isSecret = false) match
case o: Output[A | Option[A]] if c =>
o.flatMap {
case None => Output(None)
case Some(v: A) => Output(Some(v))
case a: A => Output(Some(a))
}
case _ => Output(None) // return None if condition is false

p.flatMap(f)
end when
end Output
31 changes: 31 additions & 0 deletions core/src/test/scala/besom/internal/OutputTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,35 @@ class OutputTest extends munit.FunSuite:
Context().waitForAllTasks.unsafeRunSync()
}

Vector(
(true, "value", Some("value")),
(false, "value", None)
).foreach { (cond, value, expected) =>
given Context = DummyContext().unsafeRunSync()
for
optCond <- Vector(true, false)
outCond <- Vector(true, false)
optVal <- Vector(true, false)
outVal <- Vector(true, false)
do
val c: Boolean | Option[Boolean] | Output[Boolean] | Output[Option[Boolean]] = (outCond, optCond) match
case (true, true) => Output(Option(cond))
case (true, false) => Output(cond)
case (false, true) => Some(cond)
case (false, false) => cond

val v: String | Option[String] | Output[String] | Output[Option[String]] = (outVal, optVal) match
case (true, true) => Output(Option(value))
case (true, false) => Output(value)
case (false, true) => Some(value)
case (false, false) => value

test(s"when ${cond} then ${value} (optCond: ${optCond}, outCond: ${outCond}, valOpt: ${optVal}, valOut: ${outVal})") {
val result = Output.when(c)(v)
assertEquals(result.getData.unsafeRunSync(), OutputData(expected))
}

Context().waitForAllTasks.unsafeRunSync()
}

end OutputTest

0 comments on commit f4ba7cc

Please sign in to comment.