diff --git a/src/FsToolkit.ErrorHandling.TaskResult/TaskOption.fs b/src/FsToolkit.ErrorHandling.TaskResult/TaskOption.fs index 4bafc5c6..a154a71c 100644 --- a/src/FsToolkit.ErrorHandling.TaskResult/TaskOption.fs +++ b/src/FsToolkit.ErrorHandling.TaskResult/TaskOption.fs @@ -53,3 +53,30 @@ module TaskOption = | Some v -> onSome v | None -> onNone () ) + + /// + /// Gets the value of the option if the option is Some, otherwise returns the specified default value. + /// + /// The specified default value. + /// The input option. + /// + /// The option if the option is Some, else the default value. + /// + let inline defaultValue (value: 'value) (taskOption: Task<'value option>) = + taskOption + |> Task.map (Option.defaultValue value) + + /// + /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. + /// + /// A thunk that provides a default value when evaluated. + /// The input option. + /// + /// The option if the option is Some, else the result of evaluating . + /// + let inline defaultWith + ([] defThunk: unit -> 'value) + (taskOption: Task<'value option>) + : Task<'value> = + taskOption + |> Task.map (Option.defaultWith defThunk) diff --git a/src/FsToolkit.ErrorHandling/AsyncOption.fs b/src/FsToolkit.ErrorHandling/AsyncOption.fs index 14a996a8..400adae6 100644 --- a/src/FsToolkit.ErrorHandling/AsyncOption.fs +++ b/src/FsToolkit.ErrorHandling/AsyncOption.fs @@ -52,3 +52,30 @@ module AsyncOption = | Some v -> onSome v | None -> onNone ) + + /// + /// Gets the value of the option if the option is Some, otherwise returns the specified default value. + /// + /// The specified default value. + /// The input option. + /// + /// The option if the option is Some, else the default value. + /// + let inline defaultValue (value: 'value) (asyncOption: Async<'value option>) = + asyncOption + |> Async.map (Option.defaultValue value) + + /// + /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. + /// + /// A thunk that provides a default value when evaluated. + /// The input option. + /// + /// The option if the option is Some, else the result of evaluating . + /// + let inline defaultWith + ([] defThunk: unit -> 'value) + (asyncOption: Async<'value option>) + : Async<'value> = + asyncOption + |> Async.map (Option.defaultWith defThunk) diff --git a/tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskOption.fs b/tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskOption.fs index cfef49d1..36cae0e1 100644 --- a/tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskOption.fs +++ b/tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskOption.fs @@ -154,6 +154,52 @@ let eitherTests = } ] +let defaultValueTests = + testList "TaskOption.defaultValue Tests" [ + testCaseTask "Some" + <| fun () -> + task { + let defaultValue = 10 + let expectedValue = 5 + + let taskOption = TaskOption.retn expectedValue + let! result = TaskOption.defaultValue defaultValue taskOption + Expect.equal result expectedValue "" + } + + testCaseTask "None" + <| fun () -> + task { + let expectedValue = 10 + let taskOption = Task.singleton None + let! result = TaskOption.defaultValue expectedValue taskOption + Expect.equal result expectedValue "" + } + ] + +let defaultWithTests = + testList "TaskOption.defaultWith Tests" [ + testCaseTask "Some" + <| fun () -> + task { + let defaultValue = 10 + let expectedValue = 5 + + let taskOption = TaskOption.retn expectedValue + let! result = TaskOption.defaultWith (fun () -> defaultValue) taskOption + Expect.equal result expectedValue "" + } + + testCaseTask "None" + <| fun () -> + task { + let expectedValue = 10 + let taskOption = Task.singleton None + let! result = TaskOption.defaultWith (fun () -> expectedValue) taskOption + Expect.equal result expectedValue "" + } + ] + let allTests = testList "Task Option Tests" [ mapTests @@ -162,4 +208,6 @@ let allTests = retnTests taskOptionOperatorTests eitherTests + defaultValueTests + defaultWithTests ] diff --git a/tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs b/tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs index a3b45708..41274465 100644 --- a/tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs +++ b/tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs @@ -127,6 +127,48 @@ let eitherTests = } ] +let defaultValueTests = + testList "TaskOption.defaultValue Tests" [ + testCaseAsync "Some" + <| async { + let defaultValue = 10 + let expectedValue = 5 + + let asyncOption = AsyncOption.retn expectedValue + let! result = AsyncOption.defaultValue defaultValue asyncOption + Expect.equal result expectedValue "" + } + + testCaseAsync "None" + <| async { + let expectedValue = 10 + let asyncOption = Async.singleton None + let! result = AsyncOption.defaultValue expectedValue asyncOption + Expect.equal result expectedValue "" + } + ] + +let defaultWithTests = + testList "AsyncOption.defaultWith Tests" [ + testCaseAsync "Some" + <| async { + let defaultValue = 10 + let expectedValue = 5 + + let asyncOption = AsyncOption.retn expectedValue + let! result = AsyncOption.defaultWith (fun () -> defaultValue) asyncOption + Expect.equal result expectedValue "" + } + + testCaseAsync "None" + <| async { + let expectedValue = 10 + let asyncOption = Async.singleton None + let! result = AsyncOption.defaultWith (fun () -> expectedValue) asyncOption + Expect.equal result expectedValue "" + } + ] + let allTests = testList "Async Option Tests" [ mapTests @@ -135,4 +177,6 @@ let allTests = retnTests asyncOptionOperatorTests eitherTests + defaultValueTests + defaultWithTests ]