Skip to content

Commit 6f54704

Browse files
authored
Adds CancellableResultTask functions (#203)
* updates IcedTasks to 0.5.1 * Adds helpers to CancellableTaskResult
1 parent 1fe1ab1 commit 6f54704

File tree

4 files changed

+170
-3
lines changed

4 files changed

+170
-3
lines changed

paket.dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ nuget Microsoft.NET.Test.Sdk
4747
nuget YoloDev.Expecto.TestSdk
4848
nuget Fable.Mocha
4949
nuget Fable.Core >= 4.0.0-theta-006
50-
nuget IcedTasks >= 0.5.0
50+
nuget IcedTasks >= 0.5.1
5151
framework: netstandard2.1, net7.0
5252
storage: none
5353
condition: netstandard2_1

paket.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ NUGET
10261026
FSharp.Core (7.0)
10271027
Hopac (0.5.1)
10281028
FSharp.Core (>= 4.5.2)
1029-
IcedTasks (0.5)
1029+
IcedTasks (0.5.1)
10301030
FSharp.Core (>= 7.0)
10311031
Microsoft.Bcl.AsyncInterfaces (6.0)
10321032
Microsoft.CodeCoverage (17.4) - restriction: || (== net7.0) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))

src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,3 +770,81 @@ module CancellableTaskResultCE =
770770
true
771771
)
772772
)
773+
774+
/// <summary>Lifts an item to a CancellableTaskResult.</summary>
775+
/// <param name="item">The item to be the result of the CancellableTaskResult.</param>
776+
/// <returns>A CancellableTaskResult with the item as the result.</returns>
777+
let inline singleton (item: 'item) : CancellableTaskResult<'item, 'Error> =
778+
fun _ -> Task.FromResult(Ok item)
779+
780+
781+
/// <summary>Allows chaining of CancellableTaskResult.</summary>
782+
/// <param name="binder">The continuation.</param>
783+
/// <param name="cTask">The value.</param>
784+
/// <returns>The result of the binder.</returns>
785+
let inline bind
786+
([<InlineIfLambda>] binder: 'input -> CancellableTaskResult<'output, 'error>)
787+
([<InlineIfLambda>] cTask: CancellableTaskResult<'input, 'error>)
788+
=
789+
cancellableTaskResult {
790+
let! cResult = cTask
791+
return! binder cResult
792+
}
793+
794+
/// <summary>Allows chaining of CancellableTaskResult.</summary>
795+
/// <param name="mapper">The continuation.</param>
796+
/// <param name="cTask">The value.</param>
797+
/// <returns>The result of the mapper wrapped in a CancellableTaskResult.</returns>
798+
let inline map
799+
([<InlineIfLambda>] mapper: 'input -> 'output)
800+
([<InlineIfLambda>] cTask: CancellableTaskResult<'input, 'error>)
801+
=
802+
cancellableTaskResult {
803+
let! cResult = cTask
804+
return mapper cResult
805+
}
806+
807+
/// <summary>Allows chaining of CancellableTaskResult.</summary>
808+
/// <param name="applicable">A function wrapped in a CancellableTaskResult</param>
809+
/// <param name="cTask">The value.</param>
810+
/// <returns>The result of the applicable.</returns>
811+
let inline apply
812+
([<InlineIfLambda>] applicable: CancellableTaskResult<'input -> 'output, 'error>)
813+
([<InlineIfLambda>] cTask: CancellableTaskResult<'input, 'error>)
814+
=
815+
cancellableTaskResult {
816+
let! applier = applicable
817+
let! cResult = cTask
818+
return applier cResult
819+
}
820+
821+
/// <summary>Takes two CancellableTaskResult, starts them serially in order of left to right, and returns a tuple of the pair.</summary>
822+
/// <param name="left">The left value.</param>
823+
/// <param name="right">The right value.</param>
824+
/// <returns>A tuple of the parameters passed in</returns>
825+
let inline zip
826+
([<InlineIfLambda>] left: CancellableTaskResult<'left, 'error>)
827+
([<InlineIfLambda>] right: CancellableTaskResult<'right, 'error>)
828+
=
829+
cancellableTaskResult {
830+
let! r1 = left
831+
let! r2 = right
832+
return r1, r2
833+
}
834+
835+
/// <summary>Takes two CancellableTaskResult, starts them concurrently, and returns a tuple of the pair.</summary>
836+
/// <param name="left">The left value.</param>
837+
/// <param name="right">The right value.</param>
838+
/// <returns>A tuple of the parameters passed in.</returns>
839+
let inline parallelZip
840+
([<InlineIfLambda>] left: CancellableTaskResult<'left, 'error>)
841+
([<InlineIfLambda>] right: CancellableTaskResult<'right, 'error>)
842+
=
843+
cancellableTaskResult {
844+
let! ct = getCancellationToken ()
845+
let r1 = left ct
846+
let r2 = right ct
847+
let! r1 = r1
848+
let! r2 = r2
849+
return r1, r2
850+
}

tests/FsToolkit.ErrorHandling.IcedTasks.Tests/CancellableTaskResultCE.fs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module CancellableTaskResultCE =
5656
member this.Dispose() = ()
5757
}
5858

59-
[<Tests>]
59+
6060
let cancellableTaskResultBuilderTests =
6161
testList "CancellableTaskResultBuilder" [
6262
testList "Return" [
@@ -923,3 +923,92 @@ module CancellableTaskResultCE =
923923

924924
]
925925
]
926+
927+
let functionTests =
928+
testList "functions" [
929+
testList "singleton" [
930+
testCaseAsync "Simple"
931+
<| async {
932+
let innerCall = CancellableTaskResult.singleton "lol"
933+
934+
let! someTask = innerCall
935+
936+
Expect.equal (Ok "lol") someTask ""
937+
}
938+
]
939+
testList "bind" [
940+
testCaseAsync "Simple"
941+
<| async {
942+
let innerCall = cancellableTaskResult { return "lol" }
943+
944+
let! someTask =
945+
innerCall
946+
|> CancellableTaskResult.bind (fun x -> cancellableTaskResult {
947+
return x + "fooo"
948+
}
949+
)
950+
951+
Expect.equal (Ok "lolfooo") someTask ""
952+
}
953+
]
954+
testList "map" [
955+
testCaseAsync "Simple"
956+
<| async {
957+
let innerCall = cancellableTaskResult { return "lol" }
958+
959+
let! someTask =
960+
innerCall
961+
|> CancellableTaskResult.map (fun x -> x + "fooo")
962+
963+
Expect.equal (Ok "lolfooo") someTask ""
964+
}
965+
]
966+
testList "apply" [
967+
testCaseAsync "Simple"
968+
<| async {
969+
let innerCall = cancellableTaskResult { return "lol" }
970+
let applier = cancellableTaskResult { return fun x -> x + "fooo" }
971+
972+
let! someTask =
973+
innerCall
974+
|> CancellableTaskResult.apply applier
975+
976+
Expect.equal (Ok "lolfooo") someTask ""
977+
}
978+
]
979+
980+
testList "zip" [
981+
testCaseAsync "Simple"
982+
<| async {
983+
let innerCall = cancellableTaskResult { return "fooo" }
984+
let innerCall2 = cancellableTaskResult { return "lol" }
985+
986+
let! someTask =
987+
innerCall
988+
|> CancellableTaskResult.zip innerCall2
989+
990+
Expect.equal (Ok("lol", "fooo")) someTask ""
991+
}
992+
]
993+
994+
testList "parZip" [
995+
testCaseAsync "Simple"
996+
<| async {
997+
let innerCall = cancellableTaskResult { return "fooo" }
998+
let innerCall2 = cancellableTaskResult { return "lol" }
999+
1000+
let! someTask =
1001+
innerCall
1002+
|> CancellableTaskResult.parallelZip innerCall2
1003+
1004+
Expect.equal (Ok("lol", "fooo")) someTask ""
1005+
}
1006+
]
1007+
]
1008+
1009+
[<Tests>]
1010+
let cancellableTaskResultTests =
1011+
testList "CancellableTaskResult" [
1012+
cancellableTaskResultBuilderTests
1013+
functionTests
1014+
]

0 commit comments

Comments
 (0)