diff --git a/src/gleam/javascript/promise.gleam b/src/gleam/javascript/promise.gleam index 9f65347..f9e6907 100644 --- a/src/gleam/javascript/promise.gleam +++ b/src/gleam/javascript/promise.gleam @@ -120,6 +120,26 @@ pub fn try_await( }) } +/// Run a promise returning function on the value of a result, returning a +/// promise. +/// +/// The function is only called if the value is `Ok`, and the returned promise +/// becomes the new value. If the result is `Error`, the error is returned +/// wrapped in a resolved promise. +/// +/// This is a convenience function for when you have a synchronous `Result` and +/// want to chain into an asynchronous operation without first lifting the +/// result into a promise. +pub fn try_sync( + result: Result(a, b), + then: fn(a) -> Promise(Result(c, b)), +) -> Promise(Result(c, b)) { + case result { + Ok(value) -> then(value) + Error(reason) -> resolve(Error(reason)) + } +} + /// Chain an asynchronous operation onto an array of promises, so it runs after the /// promises have resolved. /// diff --git a/test/gleam/javascript/promise_test.gleam b/test/gleam/javascript/promise_test.gleam index f669899..9af0a5f 100644 --- a/test/gleam/javascript/promise_test.gleam +++ b/test/gleam/javascript/promise_test.gleam @@ -129,6 +129,30 @@ pub fn try_await_error_test() -> Promise(Result(Int, Int)) { }) } +pub fn try_sync_ok_ok_test() -> Promise(Result(Int, Int)) { + Ok(1) + |> promise.try_sync(fn(a) { promise.resolve(Ok(a + 1)) }) + |> promise.tap(fn(a) { + let assert Ok(2) = a + }) +} + +pub fn try_sync_ok_error_test() -> Promise(Result(Int, Int)) { + Ok(1) + |> promise.try_sync(fn(a) { promise.resolve(Error(a + 1)) }) + |> promise.tap(fn(a) { + let assert Error(2) = a + }) +} + +pub fn try_sync_error_test() -> Promise(Result(Int, Int)) { + Error(1) + |> promise.try_sync(fn(a) { promise.resolve(Ok(a + 1)) }) + |> promise.tap(fn(a) { + let assert Error(1) = a + }) +} + pub fn rescue_healthy_test() { promise.resolve(1) |> promise.rescue(fn(_) { 100 })