diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 58f9e8bf..3c257a01 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"paket": {
- "version": "8.0.0",
+ "version": "8.0.3",
"commands": [
"paket"
]
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 08b84193..0882c721 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -23,8 +23,8 @@
"ghcr.io/devcontainers-contrib/features/starship:1": {},
// https://github.com/devcontainers/features/blob/main/src/dotnet/README.md
"ghcr.io/devcontainers/features/dotnet:2": {
- "version": "7.0",
- "additionalVersions": "6.0"
+ "version": "8.0",
+ "additionalVersions": "7.0,6.0"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "18"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0491abba..551d6481 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,14 @@
name: Build master
-on: [push, pull_request]
+on:
+ # Runs only on pushes to the default branch or pull requests to the default branch
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+ workflow_dispatch:
jobs:
@@ -12,7 +20,7 @@ jobs:
# Builds for Debug and Release configurations
configuration: [Debug, Release]
# Builds for Ubuntu, Windows, and macOS
- os: [ubuntu-latest, windows-latest, macOS-latest]
+ os: [ubuntu-latest, windows-latest, macOS-latest, macos-14]
runs-on: ${{ matrix.os }}
steps:
@@ -22,6 +30,8 @@ jobs:
with:
global-json-file: global.json
dotnet-version: |
+ 8.x
+ 7.x
6.x
- name: Build via Bash
@@ -44,7 +54,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
+ os: [ubuntu-latest, windows-latest, macOS-latest, macos-14]
node-version: ['18', '20', 'latest' ]
runs-on: ${{ matrix.os }}
@@ -61,6 +71,8 @@ jobs:
with:
global-json-file: global.json
dotnet-version: |
+ 8.x
+ 7.x
6.x
- name: Build via Bash
@@ -82,7 +94,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
+ os: [ubuntu-latest, windows-latest, macOS-latest, macos-14]
python-version: ['3.10', '3.11', '3.12']
runs-on: ${{ matrix.os }}
@@ -99,8 +111,9 @@ jobs:
with:
global-json-file: global.json
dotnet-version: |
+ 8.x
+ 7.x
6.x
-
- name: Build via Bash
if: runner.os != 'Windows'
run: |
diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets
index 4deb15bc..bbeec153 100644
--- a/.paket/Paket.Restore.targets
+++ b/.paket/Paket.Restore.targets
@@ -1,322 +1,325 @@
-
-
-
-
-
- $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
-
- $(MSBuildVersion)
- 15.0.0
- false
- true
-
- true
- $(MSBuildThisFileDirectory)
- $(MSBuildThisFileDirectory)..\
- $(PaketRootPath)paket-files\paket.restore.cached
- $(PaketRootPath)paket.lock
- classic
- proj
- assembly
- native
- /Library/Frameworks/Mono.framework/Commands/mono
- mono
-
-
- $(PaketRootPath)paket.bootstrapper.exe
- $(PaketToolsPath)paket.bootstrapper.exe
- $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\
-
- "$(PaketBootStrapperExePath)"
- $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
-
-
-
-
- true
- true
-
-
- True
-
-
- False
-
- $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/'))
-
-
-
-
-
-
-
-
- $(PaketRootPath)paket
- $(PaketToolsPath)paket
-
-
-
-
-
- $(PaketRootPath)paket.exe
- $(PaketToolsPath)paket.exe
-
-
-
-
-
- <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json"))
- <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"'))
- <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false
-
-
-
-
-
-
-
-
-
-
- <_PaketCommand>dotnet paket
-
-
-
-
-
- $(PaketToolsPath)paket
- $(PaketBootStrapperExeDir)paket
-
-
- paket
-
-
-
-
- <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- $(NoWarn);NU1603;NU1604;NU1605;NU1608
- false
- true
-
-
-
-
-
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)'))
-
-
-
-
-
-
- $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``))
- $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``))
-
-
-
-
- %(PaketRestoreCachedKeyValue.Value)
- %(PaketRestoreCachedKeyValue.Value)
-
-
-
-
- true
- false
- true
-
-
-
+
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+
+ $(MSBuildVersion)
+ 15.0.0
+ false
+ true
+
+ true
+ $(MSBuildThisFileDirectory)
+ $(MSBuildThisFileDirectory)..\
+ $(PaketRootPath)paket-files\paket.restore.cached
+ $(PaketRootPath)paket.lock
+ classic
+ proj
+ assembly
+ native
+ /Library/Frameworks/Mono.framework/Commands/mono
+ mono
+
+
+ $(PaketRootPath)paket.bootstrapper.exe
+ $(PaketToolsPath)paket.bootstrapper.exe
+ $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\
+
+ "$(PaketBootStrapperExePath)"
+ $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
+
+
+
+
+ true
+ true
+
+
+ True
+
+
+ False
+
+ $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/'))
+
+
+
+
+
+
+
+
+ $(PaketRootPath)paket
+ $(PaketToolsPath)paket
+
+
+
+
+
+ $(PaketRootPath)paket.exe
+ $(PaketToolsPath)paket.exe
+
+
+
+
+
+ <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json"))
+ <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"'))
+ <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false
+
+
+
+
+
+
+
+
+
+
+ <_PaketCommand>dotnet paket
+
+
+
+
+
+ $(PaketToolsPath)paket
+ $(PaketBootStrapperExeDir)paket
+
+
+ paket
+
+
+
+
+ <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(NoWarn);NU1603;NU1604;NU1605;NU1608
+ false
+ true
+
+
+
+
+
+
+
+
+ $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)'))
+
+
+
+
+
+
+ $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``))
+ $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``))
+
+
+
+
+ %(PaketRestoreCachedKeyValue.Value)
+ %(PaketRestoreCachedKeyValue.Value)
+
+
+
+
+ true
+ false
+ true
+
+
+
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached
-
- $(MSBuildProjectFullPath).paket.references
-
- $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references
-
- $(MSBuildProjectDirectory)\paket.references
-
- false
- true
- true
- references-file-or-cache-not-found
-
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)'))
- $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)'))
- references-file
- false
-
-
-
-
- false
-
-
-
-
- true
- target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths)
-
-
-
-
-
-
-
-
-
-
- false
- true
-
-
-
-
-
-
-
-
-
-
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7])
-
-
- %(PaketReferencesFileLinesInfo.PackageVersion)
- All
- runtime
- $(ExcludeAssets);contentFiles
- $(ExcludeAssets);build;buildMultitargeting;buildTransitive
- true
- true
-
-
-
-
- $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools
-
-
-
-
-
-
-
-
- $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0])
- $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1])
-
-
- %(PaketCliToolFileLinesInfo.PackageVersion)
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached
+
+ $(MSBuildProjectFullPath).paket.references
+
+ $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references
+
+ $(MSBuildProjectDirectory)\paket.references
+
+ false
+ true
+ true
+ references-file-or-cache-not-found
+
+
+
+
+ $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)'))
+ $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)'))
+ references-file
+ false
+
+
+
+
+ false
+
+
+
+
+ true
+ target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths)
+
+
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[8])
+
+
+ %(PaketReferencesFileLinesInfo.PackageVersion)
+ All
+ runtime
+ $(ExcludeAssets);contentFiles
+ $(ExcludeAssets);build;buildMultitargeting;buildTransitive
+ %(PaketReferencesFileLinesInfo.Aliases)
+ true
+ true
+
+
+
+
+
+ $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools
+
+
+
+
+
+
+
+
+ $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0])
+ $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1])
+
+
+ %(PaketCliToolFileLinesInfo.PackageVersion)
+
+
+
+
-
-
-
-
- false
-
-
-
-
-
- <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/>
-
-
-
-
-
- $(MSBuildProjectDirectory)/$(MSBuildProjectFile)
- true
- false
- true
- false
- true
- false
- true
- false
- true
- false
- true
- $(PaketIntermediateOutputPath)\$(Configuration)
- $(PaketIntermediateOutputPath)
-
-
-
- <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/>
-
-
-
-
-
-
-
-
-
+
+
+
+
+ false
+
+
+
+
+
+ <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/>
+
+
+
+
+
+ $(MSBuildProjectDirectory)/$(MSBuildProjectFile)
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(PaketIntermediateOutputPath)\$(Configuration)
+ $(PaketIntermediateOutputPath)
+
+
+
+ <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/>
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Directory.Build.props b/Directory.Build.props
index 67d20dab..f339b105 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,8 +1,8 @@
-
- true
- $(NoWarn);FS2003
- true
-
-
+
+ true
+ $(NoWarn);FS2003; NU1903; NU1904
+ true
+
+
diff --git a/FsToolkit.ErrorHandling.sln b/FsToolkit.ErrorHandling.sln
index aab8a780..f014a5d9 100644
--- a/FsToolkit.ErrorHandling.sln
+++ b/FsToolkit.ErrorHandling.sln
@@ -11,8 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D8B86171
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsToolkit.ErrorHandling.Tests", "tests\FsToolkit.ErrorHandling.Tests\FsToolkit.ErrorHandling.Tests.fsproj", "{F646F4E8-EA06-4EA8-9CD3-79778B264320}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsToolkit.ErrorHandling.TaskResult", "src\FsToolkit.ErrorHandling.TaskResult\FsToolkit.ErrorHandling.TaskResult.fsproj", "{EA9FB942-F6A4-4539-9377-A2DBE73861FC}"
-EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsToolkit.ErrorHandling.TaskResult.Tests", "tests\FsToolkit.ErrorHandling.TaskResult.Tests\FsToolkit.ErrorHandling.TaskResult.Tests.fsproj", "{868CA980-5903-480E-8360-C51F5EC83275}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsToolkit.ErrorHandling.JobResult", "src\FsToolkit.ErrorHandling.JobResult\FsToolkit.ErrorHandling.JobResult.fsproj", "{5B1EA296-538E-40E5-BF1D-6CB0F20BB52E}"
@@ -72,18 +70,6 @@ Global
{F646F4E8-EA06-4EA8-9CD3-79778B264320}.Release|x64.Build.0 = Release|Any CPU
{F646F4E8-EA06-4EA8-9CD3-79778B264320}.Release|x86.ActiveCfg = Release|Any CPU
{F646F4E8-EA06-4EA8-9CD3-79778B264320}.Release|x86.Build.0 = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|x64.ActiveCfg = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|x64.Build.0 = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|x86.ActiveCfg = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Debug|x86.Build.0 = Debug|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|Any CPU.Build.0 = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|x64.ActiveCfg = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|x64.Build.0 = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|x86.ActiveCfg = Release|Any CPU
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC}.Release|x86.Build.0 = Release|Any CPU
{868CA980-5903-480E-8360-C51F5EC83275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{868CA980-5903-480E-8360-C51F5EC83275}.Debug|Any CPU.Build.0 = Debug|Any CPU
{868CA980-5903-480E-8360-C51F5EC83275}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -220,7 +206,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{E0466000-F8E4-416B-B605-C65F7602367A} = {E28025A7-EF6A-45BF-8FA0-75E394D3D42B}
{F646F4E8-EA06-4EA8-9CD3-79778B264320} = {D8B86171-2147-49EF-8ADA-1CF8B0A20D40}
- {EA9FB942-F6A4-4539-9377-A2DBE73861FC} = {E28025A7-EF6A-45BF-8FA0-75E394D3D42B}
{868CA980-5903-480E-8360-C51F5EC83275} = {D8B86171-2147-49EF-8ADA-1CF8B0A20D40}
{5B1EA296-538E-40E5-BF1D-6CB0F20BB52E} = {E28025A7-EF6A-45BF-8FA0-75E394D3D42B}
{7DABAB8F-4A02-4992-A3A2-6C550F98C13B} = {D8B86171-2147-49EF-8ADA-1CF8B0A20D40}
diff --git a/README.md b/README.md
index 426c4ffd..8297cbd9 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ The library provides utility functions like `map`, `bind`, `apply`, `traverse`,
It was inspired by [Chessie](https://github.com/fsprojects/Chessie) and Cvdm.ErrorHandling (the latter has now been merged into FsToolkit.ErrorHandling).
-FsToolkit.ErrorHandling targets .NET Standard 2.0 and .NET Framework 4.6.1 and supports Fable.
+FsToolkit.ErrorHandling targets .NET Standard 2.0, .NET Standard2.1 and supports Fable.
## Documentation
@@ -47,6 +47,7 @@ This repository has a devcontainer setup for VSCode. For more infomation see:
* [.NET Core SDK](https://www.microsoft.com/net/download/)
* [v6.x](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
* [v7.x](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
+ * [v8.x](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
#### Optional
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 7b5e990e..40a44266 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,3 +1,13 @@
+### 5.0.0-beta001
+- BREAKING: [Remove Ply and update to FSharp 6](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/248) Credits @TheAngryByrd
+- BREAKING: [Remove MergeSources (and!) from some implementations](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/261) Credits @TheAngryByrd
+- [Use Microsoft.Bcl.AsyncInterfaces in netstandard2.0 (Allows IAsyncDisposable and IAsyncEnumerable)](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/250) Credits @TheAngryByrd
+- [Build against Net8](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/251) Credits @TheAngryByrd
+- [Fix Overload Resolution to Align to Computation Expression used](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/252) Credits @TheAngryByrd
+- [refactor!: Seq.sequenceResultM returns Array instead of seq](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) Credits @bartelink
+- [feat(Seq): sequenceResultA](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) Credits @bartelink
+
+
### 4.18.0 - October 23, 2024
- [Add Array errorhandling](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/279) Credits @DashieTM
diff --git a/benchmarks/ApplicativeTests.fs b/benchmarks/ApplicativeTests.fs
index 667dde0e..3b417a18 100644
--- a/benchmarks/ApplicativeTests.fs
+++ b/benchmarks/ApplicativeTests.fs
@@ -41,19 +41,6 @@ type Result_BindvsAndCEBenchmarks() =
}
|> ignore
- []
- member this.All_Success_And() =
- result {
- let! r1 = successSlowSync this.delay
- and! r2 = successSlowSync this.delay
- and! r3 = successSlowSync this.delay
-
- return
- r1
- + r2
- + r3
- }
- |> ignore
[]
member this.Fail_First_Bind() =
@@ -69,20 +56,6 @@ type Result_BindvsAndCEBenchmarks() =
}
|> ignore
- []
- member this.Fail_First_And() =
- result {
- let! r1 = errorSlowSync this.delay
- and! r2 = successSlowSync this.delay
- and! r3 = successSlowSync this.delay
-
- return
- r1
- + r2
- + r3
- }
- |> ignore
-
[]
member this.Fail_Mid_Bind() =
result {
@@ -97,20 +70,6 @@ type Result_BindvsAndCEBenchmarks() =
}
|> ignore
- []
- member this.Fail_Mid_And() =
- result {
- let! r1 = successSlowSync this.delay
- and! r2 = errorSlowSync this.delay
- and! r3 = successSlowSync this.delay
-
- return
- r1
- + r2
- + r3
- }
- |> ignore
-
[]
member this.Fail_Last_Bind() =
result {
@@ -124,17 +83,3 @@ type Result_BindvsAndCEBenchmarks() =
+ r3
}
|> ignore
-
- []
- member this.Fail_Last_And() =
- result {
- let! r1 = successSlowSync this.delay
- and! r2 = successSlowSync this.delay
- and! r3 = errorSlowSync this.delay
-
- return
- r1
- + r2
- + r3
- }
- |> ignore
diff --git a/benchmarks/benchmarks.fsproj b/benchmarks/benchmarks.fsproj
index 99b4a122..d7827230 100644
--- a/benchmarks/benchmarks.fsproj
+++ b/benchmarks/benchmarks.fsproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
Exe
preview
@@ -31,4 +31,4 @@
-
\ No newline at end of file
+
diff --git a/build/build.fs b/build/build.fs
index 35f65c1b..7b62ef75 100644
--- a/build/build.fs
+++ b/build/build.fs
@@ -13,11 +13,30 @@ open System.IO
open Fake.BuildServer
open FsToolkit.Build
+let environVarAsBoolOrDefault varName defaultValue =
+ let truthyConsts = [
+ "1"
+ "Y"
+ "YES"
+ "T"
+ "TRUE"
+ ]
+
+ try
+ let envvar = (Environment.environVar varName).ToUpper()
+
+ truthyConsts
+ |> List.exists ((=) envvar)
+ with _ ->
+ defaultValue
+
let project = "FsToolkit.ErrorHandling"
let summary =
"FsToolkit.ErrorHandling is a utility library to work with the Result type in F#, and allows you to do clear, simple and powerful error handling."
+let isCI = lazy (environVarAsBoolOrDefault "CI" false)
+
let isRelease (targets: Target list) =
targets
|> Seq.map (fun t -> t.Name)
@@ -93,6 +112,18 @@ let failOnBadExitAndPrint (p: ProcessResult) =
failwithf "failed with exitcode %d" p.ExitCode
+// github actions are terrible and will cancel runner operations if using too much CPU
+// https://github.com/actions/runner-images/discussions/7188#discussioncomment-6672934
+let maxCpuCount = lazy (if isCI.Value then Some(Some 2) else None)
+
+/// MaxCpu not used on unix https://github.com/fsprojects/FAKE/blob/82e38df01e4b31e5daa3623abff57e6462430395/src/app/Fake.DotNet.MSBuild/MSBuild.fs#L858-L861
+let maxCpuMsBuild =
+ lazy
+ (match maxCpuCount.Value with
+ | None -> ""
+ | Some None -> "/m"
+ | Some(Some x) -> $"/m:%d{x}")
+
module dotnet =
let watch cmdParam program args =
DotNet.exec cmdParam (sprintf "watch %s" program) args
@@ -143,11 +174,24 @@ let clean _ =
|> Seq.iter Shell.rm
-let build ctx =
- let setParams (defaults: DotNet.BuildOptions) = {
+module BuildParameters =
+ let common (defaults: MSBuild.CliArguments) = {
defaults with
+ DisableInternalBinLog = true
+ }
+
+let build ctx =
+
+ let args = [ maxCpuMsBuild.Value ]
+
+ let setParams (c: DotNet.BuildOptions) = {
+ c with
NoRestore = true
Configuration = (configuration ctx.Context.AllExecutingTargets)
+ MSBuildParams = BuildParameters.common c.MSBuildParams
+ Common =
+ c.Common
+ |> DotNet.Options.withAdditionalArgs args
}
DotNet.build setParams solutionFile
@@ -159,14 +203,22 @@ let restore _ =
ToolType = ToolType.CreateLocalTool()
})
- DotNet.restore id solutionFile
+ let setParams (c: DotNet.RestoreOptions) = {
+ c with
+ MSBuildParams = BuildParameters.common c.MSBuildParams
+ }
+
+ DotNet.restore setParams solutionFile
let npmRestore _ = Npm.install id
let dotnetTest ctx =
- let args = [ "--no-build" ]
+ let args = [
+ "--no-build"
+ maxCpuMsBuild.Value
+ ]
DotNet.test
(fun c ->
@@ -177,6 +229,7 @@ let dotnetTest ctx =
Common =
c.Common
|> DotNet.Options.withAdditionalArgs args
+ MSBuildParams = BuildParameters.common c.MSBuildParams
})
solutionFile
@@ -293,14 +346,16 @@ let dotnetPack ctx =
// ./bin from the solution root matching the "PublishNuget" target WorkingDir
OutputPath = Some distDir
Configuration = configuration ctx.Context.AllExecutingTargets
- MSBuildParams = {
- MSBuild.CliArguments.Create() with
- // "/p" (property) arguments to MSBuild.exe
- Properties = [
- ("Version", release.NugetVersion)
- ("PackageReleaseNotes", releaseNotes)
- ]
- }
+ MSBuildParams =
+ {
+ p.MSBuildParams with
+ // "/p" (property) arguments to MSBuild.exe
+ Properties = [
+ ("Version", release.NugetVersion)
+ ("PackageReleaseNotes", releaseNotes)
+ ]
+ }
+ |> BuildParameters.common
})
)
@@ -370,8 +425,8 @@ let initTargets () =
BuildServer.install [ GitHubActions.Installer ]
Option.iter (TraceSecrets.register "") githubToken.Value
- Option.iter (TraceSecrets.register "") githubToken.Value
- Option.iter (TraceSecrets.register "") githubToken.Value
+ Option.iter (TraceSecrets.register "") nugetToken.Value
+ Option.iter (TraceSecrets.register "") nugetToken.Value
Target.create "Clean" clean
diff --git a/build/build.fsproj b/build/build.fsproj
index 8a227d7a..63f5f240 100644
--- a/build/build.fsproj
+++ b/build/build.fsproj
@@ -1,13 +1,13 @@
-
- Exe
- net7.0
- false
-
-
-
-
-
-
-
\ No newline at end of file
+
+ Exe
+ net8.0
+ false
+
+
+
+
+
+
+
diff --git a/gitbook/list/sequenceResultA.md b/gitbook/list/sequenceResultA.md
index a2e0dacc..f904d42b 100644
--- a/gitbook/list/sequenceResultA.md
+++ b/gitbook/list/sequenceResultA.md
@@ -59,7 +59,7 @@ let checkIfAllPrime (numbers : int list) =
numbers
|> List.map isPrime // Result list
|> List.sequenceResultA // Result
- |> Result.map (List.forall id) // shortened version of '|> Result.map (fun boolList -> boolList |> List.map (fun x -> x = true))'
+ |> Result.map (List.forall id) // shortened version of '|> Result.map (fun boolList -> boolList |> List.forall (fun x -> x = true))
let a = [1; 2; 3; 4; 5;] |> checkIfAllPrime
// Error ["1 must be greater than 1"]
diff --git a/gitbook/resultOption/ce.md b/gitbook/resultOption/ce.md
index 8ccc5c84..2cd82b7e 100644
--- a/gitbook/resultOption/ce.md
+++ b/gitbook/resultOption/ce.md
@@ -25,8 +25,8 @@ let add x y z = x + y + z
let addResult : Result = resultOption {
let! x = Ok (Some 30)
- and! y = Error "Oops 1"
- and! z = Error "Oops 2"
+ let! y = Error "Oops 1"
+ let! z = Error "Oops 2"
return add x y z
}
// Error "Oops 1"
diff --git a/gitbook/seq/sequenceResultA.md b/gitbook/seq/sequenceResultA.md
index 6364913a..60b6761b 100644
--- a/gitbook/seq/sequenceResultA.md
+++ b/gitbook/seq/sequenceResultA.md
@@ -5,11 +5,9 @@ Namespace: `FsToolkit.ErrorHandling`
## Function Signature
```fsharp
-Result<'a, 'b> seq -> Result<'a seq, 'b seq>
+seq> -> Result<'a[], 'b[]>
```
-Note that `sequence` is the same as `traverse id`. See also [Seq.traverseResultA](traverseResultA.md).
-
This is applicative, collecting all errors. Compare the example below with [sequenceResultM](sequenceResultM.md).
See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/).
@@ -23,30 +21,27 @@ See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpfo
let tryParseInt str =
match Int32.TryParse str with
| true, x -> Ok x
- | false, _ ->
- Error (sprintf "unable to parse '%s' to integer" str)
+ | false, _ -> Error $"unable to parse '{str}' to integer"
["1"; "2"; "3"]
|> Seq.map tryParseInt
|> Seq.sequenceResultA
-// Ok [1; 2; 3]
+// Ok [| 1; 2; 3 |]
["1"; "foo"; "3"; "bar"]
|> Seq.map tryParseInt
|> Seq.sequenceResultA
-// Error ["unable to parse 'foo' to integer";
-// "unable to parse 'bar' to integer"]
+// Error [| "unable to parse 'foo' to integer"
+// "unable to parse 'bar' to integer" |]
```
### Example 2
```fsharp
// int -> Result
-let isPrime (x : int) =
- if x < 2 then
- sprintf "%i must be greater than 1" x |> Error
- elif
- x = 2 then Ok true
+let isPrime (x: int) =
+ if x < 2 then Error $"{x} must be greater than 1"
+ elif x = 2 then Ok true
else
let rec isPrime' (x : int) (i : int) =
if i * i > x then Ok true
@@ -54,22 +49,21 @@ let isPrime (x : int) =
else isPrime' x (i + 1)
isPrime' x 2
-// int seq -> Result
-let checkIfAllPrime (numbers : int seq) =
- numbers
- |> Seq.map isPrime // Result seq
- |> Seq.sequenceResultA // Result
- |> Result.map (Seq.forall id) // shortened version of '|> Result.map (fun boolSeq -> boolSeq |> Seq.map (fun x -> x = true))'
+// seq -> Result
+let checkIfAllPrime (numbers: seq) =
+ seq { for x in numbers -> isPrime x } // Result seq
+ |> Seq.sequenceResultA // Result
+ |> Result.map (Seq.forall id) // shortened version of '|> Result.map (fun results -> results |> Array.forall (fun x -> x = true))'
-let a = [1; 2; 3; 4; 5;] |> checkIfAllPrime
-// Error ["1 must be greater than 1"]
+let a = [| 1; 2; 3; 4; 5 |] |> checkIfAllPrime
+// Error [| "1 must be greater than 1" |]
-let b = [1; 2; 3; 4; 5; 0;] |> checkIfAllPrime
-// Error ["1 must be greater than 1"; "0 must be greater than 1"]
+let b = [ 1; 2; 3; 4; 5; 0 ] |> checkIfAllPrime
+// Error [| "1 must be greater than 1"; "0 must be greater than 1" |]
-let a = [2; 3; 4; 5;] |> checkIfAllPrime
+let a = seq { 2; 3; 4; 5 } |> checkIfAllPrime
// Ok false
-let a = [2; 3; 5;] |> checkIfAllPrime
+let a = seq { 2; 3; 5 } |> checkIfAllPrime
// Ok true
```
diff --git a/gitbook/seq/sequenceResultM.md b/gitbook/seq/sequenceResultM.md
index 4dddaa43..681bc0dd 100644
--- a/gitbook/seq/sequenceResultM.md
+++ b/gitbook/seq/sequenceResultM.md
@@ -5,11 +5,9 @@ Namespace: `FsToolkit.ErrorHandling`
## Function Signature
```fsharp
-Result<'a, 'b> seq -> Result<'a seq, 'b>
+seq> -> Result<'a[], 'b>
```
-Note that `sequence` is the same as `traverse id`. See also [Seq.traverseResultM](traverseResultM.md).
-
This is monadic, stopping on the first error. Compare the example below with [sequenceResultA](sequenceResultA.md).
See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/).
@@ -23,15 +21,14 @@ See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpfo
let tryParseInt str =
match Int32.TryParse str with
| true, x -> Ok x
- | false, _ ->
- Error (sprintf "unable to parse '%s' to integer" str)
+ | false, _ -> Error $"unable to parse '{str}' to integer"
["1"; "2"; "3"]
|> Seq.map tryParseInt
|> Seq.sequenceResultM
-// Ok [1; 2; 3]
+// Ok [| 1; 2; 3 |]
-["1"; "foo"; "3"; "bar"]
+seq { "1"; "foo"; "3"; "bar" }
|> Seq.map tryParseInt
|> Seq.sequenceResultM
// Error "unable to parse 'foo' to integer"
@@ -41,11 +38,9 @@ let tryParseInt str =
```fsharp
// int -> Result
-let isPrime (x : int) =
- if x < 2 then
- sprintf "%i must be greater than 1" x |> Error
- elif
- x = 2 then Ok true
+let isPrime (x: int) =
+ if x < 2 then Error $"{x} must be greater than 1"
+ elif x = 2 then Ok true
else
let rec isPrime' (x : int) (i : int) =
if i * i > x then Ok true
@@ -53,20 +48,20 @@ let isPrime (x : int) =
else isPrime' x (i + 1)
isPrime' x 2
-// int seq -> Result
-let checkIfAllPrime (numbers : int seq) =
+// int seq -> Result
+let checkIfAllPrime (numbers: seq) =
numbers
- |> Seq.map isPrime // Result seq
- |> Seq.sequenceResultM // Result
- |> Result.map (Seq.forall id) // shortened version of '|> Result.map (fun boolSeq -> boolSeq |> Seq.map (fun x -> x = true))';
+ |> Seq.map isPrime // seq>
+ |> Seq.sequenceResultM // Result
+ |> Result.map (Array.forall id) // shortened version of '|> Result.map (fun bools -> bools |> Array.forall (fun x -> x = true))'
-let a = [1; 2; 3; 4; 5;] |> checkIfAllPrime
-// Error ["1 must be greater than 1"]
+let a = [ 1; 2; 3; 4; 5 ] |> checkIfAllPrime
+// Error [| "1 must be greater than 1" |]
-let b = [1; 2; 3; 4; 5; 0;] |> checkIfAllPrime
-// Error ["1 must be greater than 1"]
+let b = [| 1; 2; 3; 4; 5; 0 |] |> checkIfAllPrime
+// Error [| "1 must be greater than 1" |]
-let a = [2; 3; 4; 5;] |> checkIfAllPrime
+let a = seq { 2; 3; 4; 5 } |> checkIfAllPrime
// Ok false
let a = [2; 3; 5;] |> checkIfAllPrime
diff --git a/global.json b/global.json
index f3980d49..a53d9835 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "7.0.201",
+ "version": "8.0.100",
"rollForward": "latestMinor"
}
-}
+}
\ No newline at end of file
diff --git a/paket.dependencies b/paket.dependencies
index 313f1028..43e61393 100644
--- a/paket.dependencies
+++ b/paket.dependencies
@@ -1,40 +1,15 @@
source https://api.nuget.org/v3/index.json
-
storage: none
-
-nuget Microsoft.SourceLink.GitHub prerelease copy_local: true
-
-
-
-
-group NetStandard2
-source https://api.nuget.org/v3/index.json
lowest_matching: true
strategy: min
-nuget FSharp.Core >= 4.7.2
-nuget Ply
-nuget Hopac
-nuget FSharp.Control.AsyncSeq
+nuget FSharp.Core >= 6.0.1
+nuget Hopac >= 0.5.1
+nuget FSharp.Control.AsyncSeq >= 3.2.1
nuget Fable.Core >= 4.2.0
-framework: netstandard2.0, net6.0
-storage: none
-condition: netstandard2_0
-
-
-
-
-group NetStandard2_1
-source https://api.nuget.org/v3/index.json
-lowest_matching: true
-strategy: min
-nuget FSharp.Core >= 7.0.0
-nuget Hopac
-nuget FSharp.Control.AsyncSeq
-nuget IcedTasks >= 0.7.0
-framework: netstandard2.1, net7.0
-storage: none
-condition: netstandard2_1
+nuget IcedTasks >= 0.11.4
+nuget Microsoft.SourceLink.GitHub prerelease copy_local: true
+nuget Microsoft.Bcl.AsyncInterfaces >= 6.0.0 framework:netstandard2.0
group Test
source https://api.nuget.org/v3/index.json
@@ -50,7 +25,7 @@ nuget Fable.Core
nuget Fable.Mocha
nuget Fable.Python
nuget Fable.Pyxpecto
-nuget Ply
+nuget Microsoft.Bcl.AsyncInterfaces >= 6.0.0
group Benchmarks
source https://api.nuget.org/v3/index.json
@@ -76,5 +51,8 @@ group Build
nuget Fake.JavaScript.Npm 5.22.0
nuget Fake.Api.GitHub 5.22.0
nuget Fake.BuildServer.GitHubActions 5.22.0
- nuget MSBuild.StructuredLogger
+ nuget MSBuild.StructuredLogger 2.2.206
nuget Octokit
+ nuget Nuget.Common >= 6.6.1
+ nuget NuGet.Protocol >= 6.6.1
+ nuget System.Security.Cryptography.Pkcs >= 7.0.2
diff --git a/paket.lock b/paket.lock
index 73301972..8115e906 100644
--- a/paket.lock
+++ b/paket.lock
@@ -1,11 +1,28 @@
STORAGE: NONE
+STRATEGY: MIN
+LOWEST_MATCHING: TRUE
NUGET
remote: https://api.nuget.org/v3/index.json
+ Fable.Core (4.2)
+ FSharp.Control.AsyncSeq (3.2.1)
+ FSharp.Core (>= 4.7.2) - restriction: >= netstandard2.0
+ Microsoft.Bcl.AsyncInterfaces (>= 5.0) - restriction: >= netstandard2.0
+ FSharp.Core (6.0.1)
+ Hopac (0.5.1)
+ FSharp.Core (>= 4.5.2) - restriction: >= netstandard2.0
+ IcedTasks (0.11.4)
+ FSharp.Core (>= 6.0.1) - restriction: >= netstandard2.0
+ Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: && (>= netstandard2.0) (< netstandard2.1)
+ Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: == netstandard2.0
+ System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net461) (&& (>= netstandard2.0) (< netstandard2.1))
Microsoft.Build.Tasks.Git (8.0) - copy_local: true
Microsoft.SourceLink.Common (8.0) - copy_local: true
Microsoft.SourceLink.GitHub (8.0) - copy_local: true
Microsoft.Build.Tasks.Git (>= 8.0)
Microsoft.SourceLink.Common (>= 8.0)
+ System.Runtime.CompilerServices.Unsafe (4.5.3) - restriction: == netstandard2.0
+ System.Threading.Tasks.Extensions (4.5.4) - restriction: == netstandard2.0
+ System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< netstandard1.0) (>= portable-net45+win8+wp8+wpa81) (< win8)) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net461) (&& (< netstandard1.0) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= wp8)
GROUP Benchmarks
STORAGE: NONE
@@ -737,153 +754,115 @@ NUGET
FSharp.Core (>= 4.7.2) - restriction: >= netstandard2.0
System.Reactive (>= 5.0) - restriction: >= netstandard2.0
FSharp.Core (6.0.3)
- Microsoft.Build.Framework (17.0) - restriction: >= netstandard2.0
- System.Security.Permissions (>= 4.7) - restriction: && (< net472) (>= netstandard2.0)
- Microsoft.Build.Utilities.Core (17.0) - restriction: >= netstandard2.0
- Microsoft.Build.Framework (>= 17.0) - restriction: >= netstandard2.0
- Microsoft.NET.StringTools (>= 1.0) - restriction: >= netstandard2.0
- Microsoft.VisualStudio.Setup.Configuration.Interop (>= 1.16.30) - restriction: >= net472
- Microsoft.Win32.Registry (>= 4.3) - restriction: && (< net472) (>= netstandard2.0)
- System.Collections.Immutable (>= 5.0) - restriction: >= netstandard2.0
- System.Configuration.ConfigurationManager (>= 4.7) - restriction: >= netstandard2.0
- System.Security.Permissions (>= 4.7) - restriction: && (< net472) (>= netstandard2.0)
- System.Text.Encoding.CodePages (>= 4.0.1) - restriction: && (< net472) (>= netstandard2.0)
- Microsoft.NET.StringTools (1.0) - restriction: >= netstandard2.0
- System.Memory (>= 4.5.4) - restriction: >= netstandard2.0
- System.Runtime.CompilerServices.Unsafe (>= 5.0) - restriction: >= netstandard2.0
- Microsoft.NETCore.Platforms (6.0.1) - restriction: || (&& (>= monoandroid) (>= netcoreapp2.0) (< netstandard1.3)) (&& (>= monoandroid) (>= netcoreapp2.1) (< netstandard1.3)) (&& (< monoandroid) (< net45) (< netcoreapp3.1) (>= netstandard2.0) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard2.0) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.5) (>= netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (>= net5.0) (< netcoreapp2.1) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (>= monotouch) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netcoreapp2.1)) (&& (>= net461) (>= netcoreapp2.0)) (&& (>= net461) (>= netcoreapp2.1)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinios)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinmac)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarintvos)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinwatchos)) (&& (>= netcoreapp2.0) (>= uap10.1)) (&& (< netcoreapp2.0) (>= netcoreapp2.1)) (&& (>= netcoreapp2.1) (< netcoreapp3.0)) (&& (>= netcoreapp2.1) (>= uap10.1))
+ Microsoft.Bcl.AsyncInterfaces (8.0) - restriction: || (&& (>= net462) (>= netstandard2.0)) (>= net472) (&& (< net5.0) (>= netstandard2.0))
+ System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1))
+ Microsoft.Build.Framework (17.9.5) - restriction: >= netstandard2.0
+ Microsoft.Win32.Registry (>= 5.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ System.Memory (>= 4.5.5) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net472) (&& (< net8.0) (>= netstandard2.0))
+ System.Security.Principal.Windows (>= 5.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ Microsoft.Build.Utilities.Core (17.9.5) - restriction: >= netstandard2.0
+ Microsoft.Build.Framework (>= 17.9.5) - restriction: >= netstandard2.0
+ Microsoft.IO.Redist (>= 6.0) - restriction: >= net472
+ Microsoft.NET.StringTools (>= 17.9.5) - restriction: >= netstandard2.0
+ Microsoft.Win32.Registry (>= 5.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ System.Collections.Immutable (>= 8.0) - restriction: >= netstandard2.0
+ System.Configuration.ConfigurationManager (>= 8.0) - restriction: >= netstandard2.0
+ System.Memory (>= 4.5.5) - restriction: || (>= net472) (&& (< net8.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net472) (&& (< net8.0) (>= netstandard2.0))
+ System.Security.Principal.Windows (>= 5.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ System.Text.Encoding.CodePages (>= 7.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ Microsoft.IO.Redist (6.0) - restriction: >= net472
+ System.Buffers (>= 4.5.1) - restriction: >= net472
+ System.Memory (>= 4.5.4) - restriction: >= net472
+ Microsoft.NET.StringTools (17.9.5) - restriction: >= netstandard2.0
+ System.Memory (>= 4.5.5) - restriction: || (>= net472) (&& (< net8.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net472) (&& (< net8.0) (>= netstandard2.0))
+ Microsoft.NETCore.Platforms (6.0.1) - restriction: || (&& (< monoandroid) (< net45) (< netcoreapp3.1) (>= netstandard2.0) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard2.0) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.5) (>= netstandard2.0) (< win8) (< wpa81)) (&& (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (>= netcoreapp2.1) (< netcoreapp3.0))
Microsoft.NETCore.Targets (5.0) - restriction: || (&& (< monoandroid) (< net45) (< netcoreapp3.1) (>= netstandard2.0) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard2.0) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.5) (>= netstandard2.0) (< win8) (< wpa81))
- Microsoft.VisualStudio.Setup.Configuration.Interop (3.1.2196) - restriction: >= net472
- Microsoft.Win32.Registry (5.0) - restriction: || (&& (< net45) (>= netstandard2.0)) (&& (< net472) (>= netstandard2.0))
+ Microsoft.Win32.Registry (5.0) - restriction: || (&& (< net45) (>= netstandard2.0)) (&& (< net472) (< net8.0) (>= netstandard2.0))
System.Buffers (>= 4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.3)) (>= monotouch) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
System.Memory (>= 4.5.4) - restriction: || (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= uap10.1)
System.Security.AccessControl (>= 5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3)) (&& (< monoandroid) (>= netcoreapp2.0)) (>= monotouch) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (>= netcoreapp2.1) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3)) (&& (< monoandroid) (>= netcoreapp2.0)) (>= monotouch) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (>= netcoreapp2.1) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
- Microsoft.Win32.SystemEvents (6.0) - restriction: >= netcoreapp3.1
Mono.Posix.NETStandard (1.0) - restriction: >= netstandard2.0
- MSBuild.StructuredLogger (2.1.787)
- Microsoft.Build.Framework (>= 16.10) - restriction: >= netstandard2.0
- Microsoft.Build.Utilities.Core (>= 16.10) - restriction: >= netstandard2.0
- Newtonsoft.Json (13.0.1) - restriction: >= netstandard2.0
- NuGet.Common (6.0) - restriction: >= netstandard2.0
- NuGet.Frameworks (>= 6.0) - restriction: || (>= net45) (>= netstandard2.0)
- NuGet.Configuration (6.0) - restriction: >= netstandard2.0
- NuGet.Common (>= 6.0) - restriction: || (>= net45) (>= netstandard2.0)
- System.Security.Cryptography.ProtectedData (>= 4.4) - restriction: && (< net45) (>= netstandard2.0)
- NuGet.Frameworks (6.0) - restriction: >= netstandard2.0
- NuGet.Packaging (6.0) - restriction: >= netstandard2.0
- Newtonsoft.Json (>= 13.0.1) - restriction: >= netstandard2.0
- NuGet.Configuration (>= 6.0) - restriction: >= netstandard2.0
- NuGet.Versioning (>= 6.0) - restriction: >= netstandard2.0
- System.Security.Cryptography.Cng (>= 5.0) - restriction: || (&& (< net472) (>= netstandard2.0)) (>= net5.0)
- System.Security.Cryptography.Pkcs (>= 5.0) - restriction: || (&& (< net472) (>= netstandard2.0)) (>= net5.0)
- NuGet.Protocol (6.0) - restriction: >= netstandard2.0
- NuGet.Packaging (>= 6.0) - restriction: >= netstandard2.0
- NuGet.Versioning (6.0) - restriction: >= netstandard2.0
+ MSBuild.StructuredLogger (2.2.206)
+ Microsoft.Build.Framework (>= 17.5) - restriction: >= netstandard2.0
+ Microsoft.Build.Utilities.Core (>= 17.5) - restriction: >= netstandard2.0
+ Newtonsoft.Json (13.0.3) - restriction: >= netstandard2.0
+ NuGet.Common (6.8)
+ NuGet.Frameworks (>= 6.8) - restriction: >= netstandard2.0
+ NuGet.Configuration (6.8) - restriction: >= netstandard2.0
+ NuGet.Common (>= 6.8) - restriction: >= netstandard2.0
+ System.Security.Cryptography.ProtectedData (>= 4.4) - restriction: && (< net472) (>= netstandard2.0)
+ NuGet.Frameworks (6.8) - restriction: >= netstandard2.0
+ NuGet.Packaging (6.8) - restriction: >= netstandard2.0
+ Newtonsoft.Json (>= 13.0.3) - restriction: >= netstandard2.0
+ NuGet.Configuration (>= 6.8) - restriction: >= netstandard2.0
+ NuGet.Versioning (>= 6.8) - restriction: >= netstandard2.0
+ System.Security.Cryptography.Pkcs (>= 6.0.4) - restriction: || (&& (< net472) (>= netstandard2.0)) (>= net5.0)
+ NuGet.Protocol (6.8)
+ NuGet.Packaging (>= 6.8) - restriction: >= netstandard2.0
+ System.Text.Json (>= 7.0.3) - restriction: || (>= net472) (&& (< net5.0) (>= netstandard2.0))
+ NuGet.Versioning (6.8) - restriction: >= netstandard2.0
Octokit (0.50)
- System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= netstandard2.0)) (&& (>= net461) (>= netstandard2.1)) (&& (< net461) (< net6.0) (>= netstandard2.0)) (&& (< net461) (>= netstandard2.0) (< netstandard2.1)) (&& (>= net5.0) (< netstandard2.1)) (&& (< net6.0) (>= netstandard2.1)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= xamarintvos)) (&& (>= netstandard2.0) (>= xamarinwatchos)) (>= xamarinios) (>= xamarinmac)
- System.Collections.Immutable (6.0) - restriction: >= netstandard2.0
- System.Memory (>= 4.5.4) - restriction: || (>= net461) (&& (< net6.0) (>= netstandard2.0))
- System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net461) (>= netstandard2.0)
- System.Configuration.ConfigurationManager (6.0) - restriction: >= netstandard2.0
- System.Security.Cryptography.ProtectedData (>= 6.0) - restriction: || (&& (< net461) (>= netstandard2.0)) (>= net6.0)
- System.Security.Permissions (>= 6.0) - restriction: || (>= net461) (>= netstandard2.0)
- System.Drawing.Common (6.0) - restriction: >= netcoreapp3.1
- Microsoft.Win32.SystemEvents (>= 6.0) - restriction: >= netcoreapp3.1
- System.Formats.Asn1 (6.0) - restriction: || (&& (< net461) (>= netstandard2.0)) (&& (>= net5.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= netcoreapp3.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= netstandard2.1)
- System.Buffers (>= 4.5.1) - restriction: || (>= net461) (&& (< net6.0) (>= netstandard2.0))
- System.Memory (>= 4.5.4) - restriction: || (>= net461) (&& (< net6.0) (>= netstandard2.0))
- System.IO (4.3) - restriction: || (&& (< monoandroid) (< net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< monoandroid) (< net46) (< netstandard1.6) (>= netstandard2.0)) (&& (< monoandroid) (>= net5.0) (< netstandard1.4)) (&& (< monoandroid) (>= net5.0) (< netstandard1.6)) (&& (< monoandroid) (>= net5.0) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (>= net5.0) (< netstandard1.4)) (&& (< net46) (>= net461) (< netstandard1.4) (>= netstandard2.0)) (&& (< net46) (>= net461) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net462) (< netstandard1.4) (>= netstandard2.0)) (&& (< net46) (>= net462) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net47) (>= netstandard2.0)) (&& (>= net461) (>= net5.0) (< netstandard1.4)) (&& (>= net461) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (>= net5.0) (< netstandard1.4)) (&& (>= net462) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard1.4)) (&& (>= net463) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard2.0)) (&& (>= net463) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net463) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net47) (< net472) (>= netstandard2.0)) (&& (>= net47) (>= net5.0))
- System.Memory (4.5.4) - restriction: || (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net5.0) (< netstandard2.1)) (>= netstandard2.0)
+ System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (>= net462) (>= netstandard2.0)) (&& (>= net462) (>= netstandard2.1)) (&& (< net462) (< net6.0) (>= netstandard2.0)) (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (>= net472) (&& (< net5.0) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.1)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (< netstandard2.1) (>= xamarintvos)) (&& (>= netstandard2.0) (< netstandard2.1) (>= xamarinwatchos)) (&& (< netstandard2.1) (>= xamarinios)) (&& (< netstandard2.1) (>= xamarinmac))
+ System.Collections.Immutable (8.0) - restriction: >= netstandard2.0
+ System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0))
+ System.Configuration.ConfigurationManager (8.0) - restriction: >= netstandard2.0
+ System.Diagnostics.EventLog (>= 8.0) - restriction: >= net7.0
+ System.Security.Cryptography.ProtectedData (>= 8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net6.0)
+ System.Diagnostics.EventLog (8.0) - restriction: >= net7.0
+ System.Formats.Asn1 (8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (&& (>= netcoreapp3.0) (< xamarintvos) (< xamarinwatchos)) (>= netstandard2.1)
+ System.Buffers (>= 4.5.1) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Memory (4.5.5) - restriction: || (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net462) (>= netstandard2.0)) (&& (>= net462) (>= netstandard2.1)) (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (>= net472) (&& (< net5.0) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.1)) (&& (< net8.0) (>= netstandard2.0)) (&& (>= netstandard2.0) (>= uap10.1))
System.Buffers (>= 4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (< uap10.1) (>= wpa81)) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
System.Numerics.Vectors (>= 4.4) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)
- System.Numerics.Vectors (>= 4.5) - restriction: >= net461
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
- System.Numerics.Vectors (4.5) - restriction: || (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net461) (>= netstandard2.0))
+ System.Numerics.Vectors (4.5) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)
System.Reactive (5.0) - restriction: >= netstandard2.0
System.Runtime.InteropServices.WindowsRuntime (>= 4.3) - restriction: && (< net472) (< netcoreapp3.1) (>= netstandard2.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net472) (&& (< netcoreapp3.1) (>= netstandard2.0)) (>= uap10.1)
- System.Runtime (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netcoreapp3.1) (>= netstandard2.0) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< monoandroid) (< net46) (< netstandard1.6) (>= netstandard2.0)) (&& (< monoandroid) (>= net5.0) (< netstandard1.4)) (&& (< monoandroid) (>= net5.0) (< netstandard1.6)) (&& (< monoandroid) (>= net5.0) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (>= net5.0) (< netstandard1.4)) (&& (< net46) (>= net461) (< netstandard1.4) (>= netstandard2.0)) (&& (< net46) (>= net461) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net462) (< netstandard1.4) (>= netstandard2.0)) (&& (< net46) (>= net462) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net47) (>= netstandard2.0)) (&& (>= net461) (>= net5.0) (< netstandard1.4)) (&& (>= net461) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (>= net5.0) (< netstandard1.4)) (&& (>= net462) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard1.4)) (&& (>= net463) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard2.0)) (&& (>= net463) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net463) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net47) (< net472) (>= netstandard2.0)) (&& (>= net47) (>= net5.0))
+ System.Runtime (4.3.1) - restriction: && (< monoandroid) (< net45) (< netcoreapp3.1) (>= netstandard2.0) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)
Microsoft.NETCore.Platforms (>= 1.1.1) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.2) (< win8) (< wp8)) (&& (< monoandroid) (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos))
Microsoft.NETCore.Targets (>= 1.1.3) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.2) (< win8) (< wp8)) (&& (< monoandroid) (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos))
- System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (>= netstandard2.0)
+ System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1) (< netstandard2.1)) (&& (< monoandroid) (< netstandard1.0) (>= netstandard2.0) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net461) (>= netstandard2.0)) (&& (>= net462) (>= netstandard2.0)) (>= net472) (&& (< net5.0) (>= net6.0)) (&& (< net5.0) (>= netstandard2.0)) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net8.0) (>= netstandard2.0)) (&& (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (< netstandard2.1) (>= xamarintvos)) (&& (>= netstandard2.0) (< netstandard2.1) (>= xamarinwatchos)) (&& (>= netstandard2.0) (>= uap10.1)) (&& (>= netstandard2.0) (>= wp8)) (&& (< netstandard2.1) (>= xamarinios)) (&& (< netstandard2.1) (>= xamarinmac))
System.Runtime.InteropServices.WindowsRuntime (4.3) - restriction: && (< net472) (< netcoreapp3.1) (>= netstandard2.0)
System.Runtime (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)
- System.Security.AccessControl (6.0) - restriction: && (< net472) (>= netstandard2.0)
+ System.Security.AccessControl (6.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< net8.0) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net472) (>= netstandard2.0)) (&& (< net8.0) (>= netcoreapp2.1)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (>= netstandard2.0) (>= uap10.1))
System.Security.Principal.Windows (>= 5.0) - restriction: || (>= net461) (&& (< net6.0) (>= netstandard2.0))
- System.Security.Cryptography.Algorithms (4.3.1) - restriction: || (&& (< monoandroid) (< net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< monoandroid) (< net46) (< netstandard1.6) (>= netstandard2.0)) (&& (< monoandroid) (>= net5.0) (< netstandard1.4)) (&& (< monoandroid) (>= net5.0) (< netstandard1.6)) (&& (< monoandroid) (>= net5.0) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (>= net5.0) (< netstandard1.4)) (&& (>= net46) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net461) (< net462) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net461) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net47) (< net472) (>= netstandard2.0)) (&& (>= net47) (>= net5.0))
- System.IO (>= 4.3) - restriction: || (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.4)) (&& (< monoandroid) (< net46) (>= netstandard1.4) (< netstandard1.6)) (&& (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net463)
- System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.4)) (&& (< monoandroid) (< net46) (>= netstandard1.4) (< netstandard1.6)) (&& (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net463)
- System.Security.Cryptography.Encoding (>= 4.3) - restriction: || (&& (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net463)
- System.Security.Cryptography.Primitives (>= 4.3) - restriction: || (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.4)) (&& (< monoandroid) (< net46) (>= netstandard1.4) (< netstandard1.6)) (&& (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (< netstandard1.4)) (&& (>= net461) (< netstandard1.6)) (>= net463)
- System.Security.Cryptography.Cng (5.0) - restriction: || (&& (< net461) (>= netstandard2.0) (< netstandard2.1)) (&& (< net472) (>= netstandard2.0)) (>= net5.0) (&& (< net6.0) (>= netcoreapp3.1)) (&& (< netcoreapp3.1) (>= netstandard2.1))
+ System.Security.Cryptography.Cng (5.0) - restriction: || (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (&& (< net6.0) (>= netstandard2.1))
Microsoft.NETCore.Platforms (>= 5.0) - restriction: && (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)
System.Formats.Asn1 (>= 5.0) - restriction: && (>= netcoreapp3.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)
- System.Security.Cryptography.Algorithms (>= 4.3.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net46) (>= netstandard1.6) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.4)) (&& (< monoandroid) (< net46) (>= netstandard1.4) (< netstandard1.6) (< uap10.1)) (&& (>= net46) (< netstandard1.4)) (&& (>= net461) (< net462) (< netstandard1.6)) (&& (>= net462) (< netstandard1.6)) (>= net47)
- System.Security.Cryptography.Encoding (4.3) - restriction: || (&& (< monoandroid) (< net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< monoandroid) (< net46) (< netstandard1.6) (>= netstandard2.0)) (&& (< monoandroid) (>= net5.0) (< netstandard1.4)) (&& (< monoandroid) (>= net5.0) (< netstandard1.6)) (&& (< monoandroid) (>= net5.0) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (>= net5.0) (< netstandard1.4)) (&& (< net46) (>= net461) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net462) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net47) (>= netstandard2.0)) (&& (>= net461) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard1.4)) (&& (>= net463) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard2.0)) (&& (>= net463) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net463) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net47) (< net472) (>= netstandard2.0)) (&& (>= net47) (>= net5.0))
- System.Security.Cryptography.Pkcs (6.0) - restriction: || (&& (< net472) (>= netstandard2.0)) (>= net5.0)
- System.Buffers (>= 4.5.1) - restriction: && (< net461) (>= netstandard2.0) (< netstandard2.1)
- System.Formats.Asn1 (>= 6.0) - restriction: || (&& (< net461) (>= netstandard2.0)) (>= netstandard2.1)
- System.Memory (>= 4.5.4) - restriction: && (< net461) (>= netstandard2.0) (< netstandard2.1)
- System.Security.Cryptography.Cng (>= 5.0) - restriction: || (&& (< net461) (>= netstandard2.0) (< netstandard2.1)) (&& (< net6.0) (>= netcoreapp3.1)) (&& (< netcoreapp3.1) (>= netstandard2.1))
- System.Security.Cryptography.Primitives (4.3) - restriction: || (&& (< monoandroid) (< net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< monoandroid) (< net46) (< netstandard1.6) (>= netstandard2.0)) (&& (< monoandroid) (>= net5.0) (< netstandard1.4)) (&& (< monoandroid) (>= net5.0) (< netstandard1.6)) (&& (< monoandroid) (>= net5.0) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (>= net46) (>= net5.0) (< netstandard1.4)) (&& (>= net46) (< netstandard1.4) (>= netstandard2.0)) (&& (< net46) (>= net461) (< netstandard1.6) (>= netstandard2.0)) (&& (< net46) (>= net47) (>= netstandard2.0)) (&& (>= net461) (< net462) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net461) (>= net5.0) (< netstandard1.4)) (&& (>= net461) (>= net5.0) (< netstandard1.6)) (&& (>= net461) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net462) (>= net5.0) (< netstandard1.4)) (&& (>= net462) (>= net5.0) (< netstandard1.6)) (&& (>= net462) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net462) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net463) (>= net5.0) (< netstandard1.4)) (&& (>= net463) (>= net5.0) (< netstandard1.6)) (&& (>= net463) (>= net5.0) (< netstandard2.0)) (&& (>= net463) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net463) (< netstandard1.6) (>= netstandard2.0)) (&& (>= net47) (< net472) (>= netstandard2.0)) (&& (>= net47) (>= net5.0)) (&& (>= net47) (< netstandard1.4) (>= netstandard2.0)) (&& (>= net47) (< netstandard1.6) (>= netstandard2.0))
- System.Security.Cryptography.ProtectedData (6.0) - restriction: || (&& (< net461) (>= netstandard2.0)) (>= net6.0)
- System.Memory (>= 4.5.4) - restriction: && (< net461) (< net6.0) (>= netstandard2.0)
- System.Security.Permissions (6.0) - restriction: >= netstandard2.0
- System.Security.AccessControl (>= 6.0) - restriction: || (>= net461) (>= netstandard2.0)
- System.Windows.Extensions (>= 6.0) - restriction: >= netcoreapp3.1
- System.Security.Principal.Windows (5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net472) (>= netstandard2.0)) (&& (< net472) (< net6.0) (>= netstandard2.0)) (>= netcoreapp2.1) (&& (>= netstandard2.0) (>= uap10.1)) (&& (>= netstandard2.0) (>= xamarintvos)) (&& (>= netstandard2.0) (>= xamarinwatchos)) (>= xamarinios) (>= xamarinmac)
+ System.Security.Cryptography.Pkcs (8.0)
+ System.Buffers (>= 4.5.1) - restriction: && (< net462) (>= netstandard2.0) (< netstandard2.1)
+ System.Formats.Asn1 (>= 8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= netstandard2.1)
+ System.Memory (>= 4.5.5) - restriction: && (< net462) (>= netstandard2.0) (< netstandard2.1)
+ System.Security.Cryptography.Cng (>= 5.0) - restriction: || (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (&& (< net6.0) (>= netstandard2.1))
+ System.Security.Cryptography.ProtectedData (8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (&& (< net472) (>= netstandard2.0)) (>= net6.0)
+ System.Memory (>= 4.5.5) - restriction: && (< net462) (< net6.0) (>= netstandard2.0)
+ System.Security.Principal.Windows (5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< net6.0) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (>= net461) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net472) (>= netstandard2.0)) (&& (>= net461) (>= netcoreapp2.0)) (&& (>= net461) (>= netcoreapp2.1)) (&& (>= net461) (>= netstandard2.0) (>= xamarintvos)) (&& (>= net461) (>= netstandard2.0) (>= xamarinwatchos)) (&& (>= net461) (>= xamarinios)) (&& (>= net461) (>= xamarinmac)) (&& (< net472) (< net8.0) (>= netstandard2.0)) (&& (< net6.0) (>= netcoreapp2.1)) (&& (< net6.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net6.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net6.0) (>= xamarinios)) (&& (< net6.0) (>= xamarinmac)) (&& (>= netstandard2.0) (>= uap10.1))
Microsoft.NETCore.Platforms (>= 5.0) - restriction: || (&& (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (>= netcoreapp2.1) (< netcoreapp3.0))
- System.Text.Encoding.CodePages (6.0) - restriction: && (< net472) (>= netstandard2.0)
- System.Memory (>= 4.5.4) - restriction: || (>= net461) (&& (< netcoreapp3.1) (>= netstandard2.0))
- System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net461) (>= netstandard2.0)
- System.Threading.Tasks.Extensions (4.5.4) - restriction: || (>= net472) (&& (< netcoreapp3.1) (>= netstandard2.0)) (&& (>= netstandard2.0) (>= uap10.1))
+ System.Text.Encoding.CodePages (8.0) - restriction: && (< net472) (< net8.0) (>= netstandard2.0)
+ System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0))
+ System.Text.Encodings.Web (8.0) - restriction: || (&& (>= net462) (>= netstandard2.0)) (>= net472) (&& (< net5.0) (>= netstandard2.0))
+ System.Buffers (>= 4.5.1) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0))
+ System.Text.Json (8.0.1) - restriction: || (>= net472) (&& (< net5.0) (>= netstandard2.0))
+ Microsoft.Bcl.AsyncInterfaces (>= 8.0) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Buffers (>= 4.5.1) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0))
+ System.Text.Encodings.Web (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0)
+ System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
+ System.ValueTuple (>= 4.5) - restriction: >= net462
+ System.Threading.Tasks.Extensions (4.5.4) - restriction: || (&& (>= net462) (>= netstandard2.0)) (>= net472) (&& (< net5.0) (>= netstandard2.0)) (&& (< netcoreapp3.1) (>= netstandard2.0)) (&& (>= netstandard2.0) (< netstandard2.1)) (&& (>= netstandard2.0) (>= uap10.1))
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< netstandard1.0) (>= portable-net45+win8+wp8+wpa81) (< win8)) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net461) (&& (< netstandard1.0) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= wp8)
- System.ValueTuple (4.5) - restriction: && (>= net45) (>= netstandard2.0)
- System.Windows.Extensions (6.0) - restriction: >= netcoreapp3.1
- System.Drawing.Common (>= 6.0) - restriction: >= netcoreapp3.1
-
-GROUP NetStandard2
-STORAGE: NONE
-STRATEGY: MIN
-LOWEST_MATCHING: TRUE
-CONDITION: NETSTANDARD2_0
-RESTRICTION: || (== net6.0) (== netstandard2.0)
-NUGET
- remote: https://api.nuget.org/v3/index.json
- Fable.Core (4.2)
- FSharp.Control.AsyncSeq (3.2.1)
- FSharp.Core (>= 4.7.2)
- Microsoft.Bcl.AsyncInterfaces (>= 5.0)
- FSharp.Core (4.7.2)
- Hopac (0.5.1)
- FSharp.Core (>= 4.5.2)
- Microsoft.Bcl.AsyncInterfaces (6.0)
- System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0)
- Ply (0.3.1)
- FSharp.Core (>= 4.6.2)
- System.Threading.Tasks.Extensions (>= 4.5.4)
- System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.0)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= wp8)) (== netstandard2.0)
- System.Threading.Tasks.Extensions (4.5.4)
- System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.0)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= wp8)) (== netstandard2.0)
-
-GROUP NetStandard2_1
-STORAGE: NONE
-STRATEGY: MIN
-LOWEST_MATCHING: TRUE
-CONDITION: NETSTANDARD2_1
-RESTRICTION: || (== net7.0) (== netstandard2.1)
-NUGET
- remote: https://api.nuget.org/v3/index.json
- FSharp.Control.AsyncSeq (3.2.1)
- FSharp.Core (>= 4.7.2)
- Microsoft.Bcl.AsyncInterfaces (>= 5.0)
- FSharp.Core (7.0.300)
- Hopac (0.5.1)
- FSharp.Core (>= 4.5.2)
- IcedTasks (0.7)
- FSharp.Core (>= 7.0)
- Microsoft.Bcl.AsyncInterfaces (6.0)
+ System.ValueTuple (4.5) - restriction: || (&& (>= net462) (>= netstandard2.0)) (>= net472)
GROUP Test
STORAGE: NONE
@@ -911,6 +890,8 @@ NUGET
FSharp.Core (7.0.402)
Hopac (0.5.1) - restriction: >= net6.0
FSharp.Core (>= 4.5.2) - restriction: >= netstandard2.0
+ Microsoft.Bcl.AsyncInterfaces (6.0)
+ System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net461) (&& (>= netstandard2.0) (< netstandard2.1))
Microsoft.CodeCoverage (17.8) - restriction: || (>= net462) (>= netcoreapp3.1)
Microsoft.NET.Test.Sdk (17.8)
Microsoft.CodeCoverage (>= 17.8) - restriction: || (>= net462) (>= netcoreapp3.1)
@@ -924,9 +905,6 @@ NUGET
Mono.Cecil (0.11.5) - restriction: >= net6.0
Newtonsoft.Json (13.0.3) - restriction: >= netcoreapp3.1
NuGet.Frameworks (6.8) - restriction: >= netcoreapp3.1
- Ply (0.3.1)
- FSharp.Core (>= 4.6.2) - restriction: >= netstandard2.0
- System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: >= netstandard2.0
System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard2.0)) (&& (>= monotouch) (>= netcoreapp3.1)) (&& (>= net45) (>= netcoreapp3.1) (< netstandard2.0)) (&& (>= net461) (>= netcoreapp3.1)) (&& (>= net462) (>= netcoreapp3.1)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinios)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinmac)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarintvos)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinwatchos)) (&& (< netcoreapp2.0) (>= netcoreapp3.1)) (&& (>= netcoreapp3.1) (< netstandard1.1) (>= win8)) (&& (>= netcoreapp3.1) (< netstandard2.0) (>= wpa81))
System.Collections.Immutable (8.0) - restriction: >= netcoreapp3.1
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0))
@@ -936,8 +914,8 @@ NUGET
System.Reflection.Metadata (8.0) - restriction: >= netcoreapp3.1
System.Collections.Immutable (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0)
System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0))
- System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (< netcoreapp2.1) (>= netcoreapp3.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard2.0)) (&& (< monoandroid) (< netstandard1.0) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netcoreapp3.1)) (&& (>= net45) (>= netcoreapp3.1) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net461) (>= netcoreapp3.1)) (&& (>= net461) (>= netstandard2.0)) (&& (>= net462) (>= net6.0)) (&& (>= net462) (>= netcoreapp3.1)) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinios)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinmac)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarintvos)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinwatchos)) (&& (< netcoreapp2.0) (>= netcoreapp3.1)) (&& (>= netcoreapp3.1) (< netstandard1.1) (>= win8)) (&& (>= netcoreapp3.1) (< netstandard2.0) (>= wpa81)) (&& (>= netcoreapp3.1) (>= uap10.1)) (&& (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= wp8))
- System.Threading.Tasks.Extensions (4.5.4) - restriction: >= netstandard2.0
+ System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (< netcoreapp2.1) (>= netcoreapp3.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard1.1)) (&& (< monoandroid) (>= netcoreapp3.1) (< netstandard2.0)) (&& (< monoandroid) (< netstandard1.0) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netcoreapp3.1)) (&& (>= net45) (>= netcoreapp3.1) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (>= net461) (&& (>= net462) (>= net6.0)) (&& (>= net462) (>= netcoreapp3.1)) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinios)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinmac)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarintvos)) (&& (< net6.0) (>= netcoreapp3.1) (>= xamarinwatchos)) (&& (< netcoreapp2.0) (>= netcoreapp3.1)) (&& (>= netcoreapp3.1) (< netstandard1.1) (>= win8)) (&& (>= netcoreapp3.1) (< netstandard2.0) (>= wpa81)) (&& (>= netcoreapp3.1) (>= uap10.1)) (&& (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= wp8))
+ System.Threading.Tasks.Extensions (4.5.4) - restriction: || (>= net461) (&& (>= netstandard2.0) (< netstandard2.1))
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< netstandard1.0) (>= portable-net45+win8+wp8+wpa81) (< win8)) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.1) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= net461) (&& (< netstandard1.0) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= wp8)
YoloDev.Expecto.TestSdk (0.14.3)
Expecto (>= 10.0 < 11.0) - restriction: >= net6.0
diff --git a/playground.fsx b/playground.fsx
new file mode 100644
index 00000000..f3772be8
--- /dev/null
+++ b/playground.fsx
@@ -0,0 +1,305 @@
+#r "nuget: FsToolkit.ErrorHandling.TaskResult"
+
+let inline id x = x
+
+open FsToolkit.ErrorHandling
+
+Result.ofChoice
+module Operators =
+
+ let inline bindM builder m ([] f) =
+ (^M: (member Bind: 'd -> ('e -> 'c) -> 'c) (builder, m, f))
+
+ let inline bind2M builder m1 m2 f =
+ (^M: (member Bind2: 'a -> 'b -> ('e * 'f -> 'c) -> 'c) (builder, m1, m2, f))
+
+ let inline delayM builder x =
+ (^M: (member Delay: (unit -> 'a) -> 'c) (builder, x))
+
+ /// Inject a value into the monadic type
+ let inline returnM builder x =
+ (^M: (member Return: 'b -> 'c) (builder, x))
+
+ let inline returnFromM builder x =
+ (^M: (member ReturnFrom: 'b -> 'c) (builder, x))
+
+ let inline bindReturnM builder m ([] f) =
+ (^M: (member BindReturn: 'd -> ('e -> 'c) -> 'f) (builder, m, f))
+
+ let inline bind2ReturnM builder m1 m2 ([] f) =
+ (^M: (member Bind2Return: 'a -> 'b -> ('c * 'd -> 'e) -> 'f) (builder, m1, m2, f))
+
+ let inline mergeSourcesM builder m1 m2 =
+ (^M: (member MergeSources: 'a * 'b -> 'c) (builder, m1, m2))
+
+ let inline mergeSources3M builder m1 m2 m3 =
+ (^M: (member MergeSources3: 'a * 'b * 'c -> 'd) (builder, m1, m2, m3))
+
+ let inline liftM builder m ([] f) =
+ bindM builder m
+ <| fun m1 -> returnM builder (f m1)
+
+ let inline lift2M builder1 builder2 m1 m2 ([] f) =
+ bindM builder1 m1
+ <| fun m1' ->
+ liftM builder2 m2
+ <| fun m2' -> (f m1' m2')
+
+ /// Sequential application
+ let inline applyM (builder1: ^M1) (builder2: ^M2) f m =
+ lift2M builder1 builder2 f m
+ <| fun f x -> f x
+
+ /// Sequential application
+ let inline zipM (builder1: ^M1) (builder2: ^M2) m1 m2 =
+ lift2M builder1 builder2 m1 m2
+ <| fun m1' m2' -> (m1', m2')
+
+
+module Async =
+ let inline bind ([] f) x = Operators.bindM async x f
+ let inline delay x = Operators.delayM async x
+ let inline singleton x = Operators.returnM async x
+ let inline returnFrom x = Operators.returnFromM async x
+ let inline bindReturn ([] f) x = Operators.liftM async x f
+ let inline map ([] f) x = bindReturn f x
+ let inline mergeSources x y = Operators.zipM async async x y
+ let inline zip x y = mergeSources x y
+ let inline apply f x = Operators.applyM async async f x
+
+ let inline flatten x = bind id x
+
+module Result =
+ open FsToolkit.ErrorHandling
+
+ let inline either ([] okF) ([] errorF) =
+ function
+ | Ok x -> okF x
+ | Error e -> errorF e
+
+ let inline bind ([] f) x = Operators.bindM result x f
+ let inline delay x = Operators.delayM result x
+ let inline singleton x = Operators.returnM result x
+ let inline returnFrom x = Operators.returnFromM result x
+ let inline bindReturn ([] f) x = Operators.bindReturnM result x f
+ let inline map ([] f) x = bindReturn f x
+ let inline mergeSources x y = Operators.mergeSourcesM result x y
+ let inline zip x y = mergeSources x y
+
+ let inline apply f x =
+ mergeSources f x
+ |> bindReturn (fun (f', x') -> f' x')
+
+ let inline sequence builder f x =
+ x
+ |> either
+ (fun x -> Operators.bindReturnM builder x f)
+ (fun x ->
+ x
+ |> Result.Error
+ |> Operators.returnM builder
+ )
+
+ let inline sequenceLift builder f x =
+ x
+ |> either
+ (fun x -> Operators.liftM builder x f)
+ (fun x ->
+ x
+ |> Result.Error
+ |> Operators.returnM builder
+ )
+
+ let inline sequenceAsync x = sequenceLift async Ok x
+
+ let inline sequenceAsyncResult x = sequenceLift async id x
+
+ let inline flatten x = bind id x
+
+module AsyncResult =
+
+ type AsyncResultBuilder() =
+ member inline _.Return x = Async.singleton (Result.singleton x)
+
+ member inline _.Bind(m, f: 'a -> Async>) =
+ m
+ |> Async.bind (fun x ->
+ Result.map f x
+ |> Result.sequenceAsyncResult
+ )
+
+ member inline _.Source(x: Async>) = x
+
+ []
+ module AsyncResultBuilderExt =
+ open System.Threading.Tasks
+
+ type AsyncResultBuilder with
+
+ member inline _.Source(x: Async<'a>) = Async.map Ok x
+
+ member inline _.Source(x: Task<'a>) =
+ task {
+ let! x = x
+ return Ok x
+ }
+ |> Async.AwaitTask
+
+ member inline _.Source(x: Result<_, _>) = Async.singleton x
+
+ let asyncResult = AsyncResultBuilder()
+
+ let inline bind ([] f) x = Operators.bindM asyncResult x f
+ let inline singleton x = Operators.returnM asyncResult x
+
+ let example () =
+ asyncResult {
+ let! x = singleton 1
+ let! y = singleton 2
+ let! z = Async.singleton 3
+ let! a = Result.singleton 4
+
+ return
+ x
+ + y
+ + z
+ + a
+ }
+
+
+
+module DisposableOptionThings =
+ open System
+ open System.Threading.Tasks
+
+ []
+ []
+ []
+ []
+ type DisposableOption<'a when 'a :> IDisposable> =
+ | None
+ | Some of 'a
+ interface IDisposable with
+ member this.Dispose() =
+ match this with
+ | None -> ()
+ | Some x -> x.Dispose()
+
+ static member inline OfObj<'a when 'a :> IDisposable> (x: 'a) =
+ if box x |> isNull then None else Some x
+
+ static member inline ToOption(x: DisposableOption<'a>) =
+ match x with
+ | None -> Option.None
+ | Some x -> Option.Some x
+
+ static member inline ToValueOption(x: DisposableOption<'a>) =
+ match x with
+ | None -> ValueOption.None
+ | Some x -> ValueOption.Some x
+
+ static member inline OfOption (x: 'a Option) =
+ match x with
+ | Option.None -> None
+ | Option.Some x -> Some x
+
+ static member inline OfValueOption (x: 'a ValueOption) =
+ match x with
+ | ValueNone -> None
+ | ValueSome x -> Some x
+
+ static member inline op_Implicit (x: 'a) =
+ DisposableOption.OfObj x
+
+ static member inline op_Implicit (x: 'a DisposableOption) =
+ DisposableOption.ToOption x
+
+ static member inline op_Implicit (x: 'a DisposableOption) =
+ DisposableOption.ToValueOption x
+
+ static member inline op_Implicit (x: 'a Option) =
+ DisposableOption.OfOption x
+
+ static member inline op_Imp licit (x: 'a ValueOption) =
+ DisposableOption.OfValueOption x
+
+
+ []
+ module DisposableOption =
+ let inline bind f x =
+ match x with
+ | DisposableOption.Some x -> f x
+ | DisposableOption.None -> None
+ let inline map f x =
+ match x with
+ | DisposableOption.Some x -> Some (f x)
+ | DisposableOption.None -> None
+ let inline iter f x =
+ match x with
+ | DisposableOption.Some x -> f x
+ | DisposableOption.None -> ()
+
+
+ []
+ type AsyncDisposableOption<'a when 'a :> IAsyncDisposable> =
+ | Some of 'a
+ | None
+ interface IAsyncDisposable with
+ member this.DisposeAsync() =
+ match this with
+ | Some x -> x.DisposeAsync()
+ | None -> ValueTask()
+
+ static member inline ofObj (x: 'a) =
+ if box x |> isNull then None else Some x
+
+ member inline x.toOption() =
+ match x with
+ | Some x -> Option.Some x
+ | None -> Option.None
+
+ member inline x.toValueOption() =
+ match x with
+ | Some x -> ValueOption.Some x
+ | None -> ValueOption.None
+
+ static member inline ofOption (x: 'a Option) =
+ match x with
+ | Option.Some x -> Some x
+ | Option.None -> None
+
+ static member inline ofValueOption (x: 'a ValueOption) =
+ match x with
+ | ValueOption.ValueSome x -> Some x
+ | ValueOption.ValueNone -> None
+
+ static member inline op_Implicit (x: 'a) =
+ AsyncDisposableOption.ofObj x
+
+ static member inline op_Implicit (x: 'a AsyncDisposableOption) =
+ x.toOption()
+
+ static member inline op_Implicit (x: 'a AsyncDisposableOption) =
+ x.toValueOption()
+
+ static member inline op_Implicit (x: 'a Option) =
+ AsyncDisposableOption.ofOption x
+
+ static member inline op_Implicit (x: 'a ValueOption) =
+ AsyncDisposableOption.ofValueOption x
+
+module Examples =
+ open DisposableOptionThings
+ open System.Diagnostics
+
+ let inline implicitConv (x: ^T) : ^U = ((^T or ^U) : (static member op_Implicit : ^T -> ^U) (x))
+ let inline (!>) x = implicitConv x
+ let inline (|!>) x f = f (!> x)
+
+ let activitySource = new ActivitySource("Playground.App")
+
+ let example () =
+ use a = activitySource.StartActivity("lol") |> DisposableOption.OfObj
+ a |!> Option.iter(fun a -> a.AddTag("hello", "world") |> ignore)
+ ()
+
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index c4be768f..65508527 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -4,7 +4,7 @@
FsToolkit.ErrorHandling is an extensive utility library based around the F# Result type, enabling consistent and powerful error handling.
demystifyfp, TheAngryByrd
- Copyright © 2018-23
+ Copyright © 2018-24
https://demystifyfp.gitbook.io/fstoolkit-errorhandling
MIT
README.md
diff --git a/src/FsToolkit.ErrorHandling.AsyncSeq/paket.references b/src/FsToolkit.ErrorHandling.AsyncSeq/paket.references
index 1e2b033b..3df8daa9 100644
--- a/src/FsToolkit.ErrorHandling.AsyncSeq/paket.references
+++ b/src/FsToolkit.ErrorHandling.AsyncSeq/paket.references
@@ -1,6 +1,4 @@
Microsoft.SourceLink.GitHub
-
-group NetStandard2
- FSharp.Control.AsyncSeq
-group NetStandard2_1
- FSharp.Control.AsyncSeq
\ No newline at end of file
+FSharp.Core
+FSharp.Control.AsyncSeq
+Microsoft.Bcl.AsyncInterfaces
diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs
new file mode 100644
index 00000000..8e79edc1
--- /dev/null
+++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs
@@ -0,0 +1,1379 @@
+namespace FsToolkit.ErrorHandling
+
+
+/// Contains methods to build Tasks using the F# computation expression syntax
+[]
+module CancellableTaskResultBuilderBase =
+ open System
+ open System.Runtime.CompilerServices
+ open System.Threading
+ open System.Threading.Tasks
+ open Microsoft.FSharp.Core
+ open Microsoft.FSharp.Core.CompilerServices
+ open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
+ open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+ open Microsoft.FSharp.Collections
+ open System.Collections.Generic
+ open IcedTasks
+
+
+ /// CancellationToken -> Task>
+ type CancellableTaskResult<'T, 'Error> = CancellableTask>
+
+
+ /// The extra data stored in ResumableStateMachine for tasks
+ []
+ type CancellableTaskResultBuilderBaseStateMachineData<'T, 'Error, 'Builder> =
+ []
+ val mutable CancellationToken: CancellationToken
+
+ []
+ val mutable Result: Result<'T, 'Error>
+
+ []
+ val mutable MethodBuilder: 'Builder
+
+ member inline this.IsResultError = Result.isError this.Result
+
+ /// Throws a if this token has had cancellation requested.
+ /// The token has had cancellation requested.
+ /// The associated has been disposed.
+ member inline this.ThrowIfCancellationRequested() =
+ this.CancellationToken.ThrowIfCancellationRequested()
+
+ /// This is used by the compiler as a template for creating state machine structs
+ and CancellableTaskResultBuilderBaseStateMachine<'TOverall, 'Error, 'Builder> =
+ ResumableStateMachine>
+
+ /// Represents the runtime continuation of a cancellableTasks state machine created dynamically
+ and CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, 'Builder> =
+ ResumptionFunc>
+
+ /// Represents the runtime continuation of a cancellableTasks state machine created dynamically
+ and CancellableTaskResultBuilderBaseResumptionDynamicInfo<'TOverall, 'Error, 'Builder> =
+ ResumptionDynamicInfo>
+
+ /// A special compiler-recognised delegate type for specifying blocks of cancellableTasks code with access to the state machine
+ and CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode, 'T>
+
+ ///
+ /// Contains methods to build TaskLikes using the F# computation expression syntax
+ ///
+ type CancellableTaskResultBuilderBase() =
+ /// Creates a CancellableTasks that runs generator
+ /// The function to run
+ /// A CancellableTasks that runs generator
+ member inline _.Delay
+ ([] generator:
+ unit -> CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>)
+ : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode.Delay(fun () -> generator ())
+
+ /// Creates A CancellableTasks that just returns ().
+ ///
+ /// The existence of this method permits the use of empty else branches in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// A CancellableTasks that returns ().
+ []
+ member inline _.Zero
+ ()
+ : CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder> =
+ ResumableCode.Zero()
+
+ /// Creates A Computation that returns the result v.
+ ///
+ /// A cancellation check is performed when the computation is executed.
+ ///
+ /// The existence of this method permits the use of return in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// The value to return from the computation.
+ ///
+ /// A cancellableTasks that returns value when executed.
+ member inline _.Return
+ (value: 'T)
+ : CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, 'Builder> =
+ CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, 'Builder>(fun sm ->
+ sm.Data.Result <- Ok value
+ true
+ )
+
+ /// Creates a CancellableTasks that first runs task1
+ /// and then runs computation2, returning the result of computation2.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of expression sequencing in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// The first part of the sequenced computation.
+ /// The second part of the sequenced computation.
+ ///
+ /// A CancellableTasks that runs both of the computations sequentially.
+ member inline _.Combine
+ (
+ task1: CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder>,
+ task2: CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode.Combine(
+ task1,
+ (CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>(fun sm ->
+ if sm.Data.IsResultError then true else task2.Invoke(&sm)
+ ))
+ )
+
+ /// Creates A CancellableTasks that runs computation repeatedly
+ /// until guard() becomes false.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of while in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// The function to determine when to stop executing computation.
+ /// The function to be executed. Equivalent to the body
+ /// of a while expression.
+ ///
+ /// A CancellableTasks that behaves similarly to a while loop when run.
+ member inline _.While
+ (
+ guard: unit -> bool,
+ computation: CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder> =
+ let mutable keepGoing = true
+
+ ResumableCode.While(
+ (fun () ->
+ keepGoing
+ && guard ()
+ ),
+ CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder>(fun sm ->
+ if sm.Data.IsResultError then
+ keepGoing <- false
+ true
+ else
+ computation.Invoke(&sm)
+ )
+ )
+
+ /// Creates A CancellableTasks that runs computation and returns its result.
+ /// If an exception happens then catchHandler(exn) is called and the resulting computation executed instead.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of try/with in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ /// The function to run when computation throws an exception.
+ ///
+ /// A CancellableTasks that executes computation and calls catchHandler if an
+ /// exception is thrown.
+ member inline _.TryWith
+ (
+ computation: CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>,
+ catchHandler:
+ exn -> CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode.TryWith(computation, catchHandler)
+
+ /// Creates A CancellableTasks that runs computation. The action compensation is executed
+ /// after computation completes, whether computation exits normally or by an exception. If compensation raises an exception itself
+ /// the original exception is discarded and the new exception becomes the overall result of the computation.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of try/finally in the
+ /// cancellableTasks { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ /// The action to be run after computation completes or raises an
+ /// exception (including cancellation).
+ ///
+ /// A CancellableTasks that executes computation and compensation afterwards or
+ /// when an exception is raised.
+ member inline _.TryFinally
+ (
+ computation: CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>,
+ compensation: unit -> unit
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode.TryFinally(
+ computation,
+ ResumableCode<_, _>(fun _ ->
+ compensation ()
+ true
+ )
+ )
+
+
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
+ []
+ static member inline BindDynamic
+ (
+ sm:
+ byref>>,
+ [] getAwaiter: CancellationToken -> 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : bool =
+ sm.Data.ThrowIfCancellationRequested()
+
+ let mutable awaiter = getAwaiter sm.Data.CancellationToken
+
+ let cont =
+ (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, _>(fun sm ->
+ let result = Awaiter.GetResult awaiter
+
+ match result with
+ | Ok result -> (continuation result).Invoke(&sm)
+ | Error e ->
+ sm.Data.Result <- Error e
+ true
+ ))
+
+ // shortcut to continue immediately
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+
+ /// Creates A CancellableTask that runs computation, and when
+ /// computation generates a result T, runs binder res.
+ ///
+ /// A cancellation check is performed when the computation is executed.
+ ///
+ /// The existence of this method permits the use of let! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The computation to provide an unbound result.
+ /// The function to bind the result of computation.
+ ///
+ /// A CancellableTask that performs a monadic bind on the result
+ /// of computation.
+ []
+ member inline _.Bind
+ (
+ [] getAwaiterTResult: CancellationToken -> 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> =
+
+ CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm ->
+ if __useResumableCode then
+ //-- RESUMABLE CODE START
+ sm.Data.ThrowIfCancellationRequested()
+ // Get an awaiter from the Awaiter
+ let mutable awaiter = getAwaiterTResult sm.Data.CancellationToken
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ // This will yield with __stack_yield_fin = false
+ // This will resume with __stack_yield_fin = true
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+
+ match result with
+ | Ok result -> (continuation result).Invoke(&sm)
+ | Error e ->
+ sm.Data.Result <- Error e
+ true
+ else
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(&sm.Data.MethodBuilder, &awaiter, &sm)
+
+ false
+ else
+ CancellableTaskResultBuilderBase.BindDynamic(
+ &sm,
+ getAwaiterTResult,
+ continuation
+ )
+ //-- RESUMABLE CODE END
+ )
+
+
+ /// Creates a CancellableTask that enumerates the sequence seq
+ /// on demand and runs body for each element.
+ ///
+ /// A cancellation check is performed on each iteration of the loop.
+ ///
+ /// The existence of this method permits the use of for in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The sequence to enumerate.
+ /// A function to take an item from the sequence and create
+ /// A CancellableTask. Can be seen as the body of the for expression.
+ ///
+ /// A CancellableTask that will enumerate the sequence and run body
+ /// for each element.
+ member inline this.For
+ (
+ sequence: seq<'T>,
+ body: 'T -> CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder> =
+ ResumableCode.Using(
+ sequence.GetEnumerator(),
+ // ... and its body is a while loop that advances the enumerator and runs the body on each element.
+ (fun e ->
+ this.While(
+ (fun () -> e.MoveNext()),
+ CancellableTaskResultBuilderBaseCode<'TOverall, unit, 'Error, 'Builder>(fun
+ sm ->
+ (body e.Current).Invoke(&sm)
+ )
+ )
+ )
+ )
+
+ /// Creates A CancellableTask that runs computation. The action compensation is executed
+ /// after computation completes, whether computation exits normally or by an exception. If compensation raises an exception itself
+ /// the original exception is discarded and the new exception becomes the overall result of the computation.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of try/finally in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ /// The action to be run after computation completes or raises an
+ /// exception.
+ ///
+ /// A CancellableTask that executes computation and compensation afterwards or
+ /// when an exception is raised.
+ member inline internal this.TryFinallyAsync
+ (
+ computation: CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>,
+ compensation: unit -> 'Awaitable
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ ResumableCode.TryFinallyAsync(
+ computation,
+ ResumableCode<_, _>(fun sm ->
+
+ if __useResumableCode then
+ let mutable __stack_condition_fin = true
+ let mutable awaiter = compensation ()
+
+ if not (Awaiter.IsCompleted awaiter) then
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_condition_fin <- __stack_yield_fin
+
+ if __stack_condition_fin then
+ Awaiter.GetResult awaiter
+ else
+
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
+
+ __stack_condition_fin
+ else
+ let mutable awaiter = compensation ()
+
+ let cont =
+ CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, 'Builder>(fun
+ sm ->
+ Awaiter.GetResult awaiter
+ true
+ )
+
+ // shortcut to continue immediately
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <-
+ (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+ )
+ )
+
+ /// Creates A CancellableTask that runs binder(resource).
+ /// The action resource.DisposeAsync() is executed as this computation yields its result
+ /// or if the CancellableTask exits by an exception or by cancellation.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of use and use! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The resource to be used and disposed.
+ /// The function that takes the resource and returns an asynchronous
+ /// computation.
+ ///
+ /// A CancellableTask that binds and eventually disposes resource.
+ ///
+ member inline this.Using
+ (
+ resource: #IAsyncDisposable,
+ binder:
+ #IAsyncDisposable
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder> =
+ this.TryFinallyAsync(
+ (fun sm -> (binder resource).Invoke(&sm)),
+ (fun () ->
+ if not (isNull (box resource)) then
+ resource.DisposeAsync()
+ |> Awaitable.GetAwaiter
+ else
+ ValueTask()
+ |> Awaitable.GetAwaiter
+ )
+ )
+
+
+ member inline internal _.WhileAsync
+ (
+ [] condition,
+ body: CancellableTaskResultBuilderBaseCode<_, unit, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<_, unit, 'Error, 'Builder> =
+ let mutable condition_res = true
+
+ ResumableCode.While(
+ (fun () -> condition_res),
+ CancellableTaskResultBuilderBaseCode<_, unit, 'Error, 'Builder>(fun sm ->
+ if __useResumableCode then
+
+ let mutable __stack_condition_fin = true
+ let mutable awaiter = condition ()
+
+ if Awaiter.IsCompleted awaiter then
+
+ __stack_condition_fin <- true
+
+ condition_res <- Awaiter.GetResult awaiter
+ else
+
+ // This will yield with __stack_fin = false
+ // This will resume with __stack_fin = true
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_condition_fin <- __stack_yield_fin
+
+ if __stack_condition_fin then
+ condition_res <- Awaiter.GetResult awaiter
+
+
+ if __stack_condition_fin then
+
+ if condition_res then body.Invoke(&sm) else true
+ else
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
+
+ false
+ else
+
+ let mutable awaiter = condition ()
+
+ let cont =
+ CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, 'Builder>(fun
+ sm ->
+ condition_res <- Awaiter.GetResult awaiter
+ if condition_res then body.Invoke(&sm) else true
+ )
+
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <-
+ (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+ )
+ )
+
+ member inline this.For
+ (
+ source: #IAsyncEnumerable<'T>,
+ body: 'T -> CancellableTaskResultBuilderBaseCode<_, unit, 'Error, 'Builder>
+ ) : CancellableTaskResultBuilderBaseCode<_, _, 'Error, 'Builder> =
+
+ CancellableTaskResultBuilderBaseCode<_, _, 'Error, 'Builder>(fun sm ->
+ this
+ .Using(
+ source.GetAsyncEnumerator sm.Data.CancellationToken,
+ (fun (e: IAsyncEnumerator<'T>) ->
+ this.WhileAsync(
+ (fun () -> Awaitable.GetAwaiter(e.MoveNextAsync())),
+ (fun sm -> (body e.Current).Invoke(&sm))
+ )
+ )
+
+ )
+ .Invoke(&sm)
+ )
+
+
+ ///
+ []
+ module LowPriority2 =
+ // Low priority extensions
+ type CancellableTaskResultBuilderBase with
+
+
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
+ []
+ static member inline BindDynamic
+ (
+ sm:
+ byref>>,
+ [] getAwaiter: CancellationToken -> 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : bool =
+ sm.Data.ThrowIfCancellationRequested()
+
+ let mutable awaiter = getAwaiter sm.Data.CancellationToken
+
+ let cont =
+ (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, _>(fun sm ->
+ let result = Awaiter.GetResult awaiter
+
+ (continuation result).Invoke(&sm)
+ ))
+
+ // shortcut to continue immediately
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <-
+ (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+
+ /// Creates A CancellableTask that runs computation, and when
+ /// computation generates a result T, runs binder res.
+ ///
+ /// A cancellation check is performed when the computation is executed.
+ ///
+ /// The existence of this method permits the use of let! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The computation to provide an unbound result.
+ /// The function to bind the result of computation.
+ ///
+ /// A CancellableTask that performs a monadic bind on the result
+ /// of computation.
+ []
+ member inline _.Bind
+ (
+ [] getAwaiterT: CancellationToken -> 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> =
+
+ CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm ->
+ if __useResumableCode then
+ //-- RESUMABLE CODE START
+ sm.Data.ThrowIfCancellationRequested()
+ // Get an awaiter from the Awaiter
+ let mutable awaiter = getAwaiterT sm.Data.CancellationToken
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ // This will yield with __stack_yield_fin = false
+ // This will resume with __stack_yield_fin = true
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+
+ (continuation result).Invoke(&sm)
+ else
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
+
+ false
+ else
+ CancellableTaskResultBuilderBase.BindDynamic(
+ &sm,
+ getAwaiterT,
+ continuation
+ )
+ //-- RESUMABLE CODE END
+ )
+
+
+ /// Delegates to the input computation.
+ ///
+ /// The existence of this method permits the use of return! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ ///
+ /// The input computation.
+ []
+ member inline this.ReturnFrom
+ ([] getAwaiterT: CancellationToken -> 'Awaiter)
+ =
+ this.Bind(
+ getAwaiterT = (fun ct -> getAwaiterT ct),
+ continuation = (fun v -> this.Return v)
+ )
+
+
+ // []
+ // member inline this.BindReturn
+ // (
+ // [] getAwaiterT: CancellationToken -> 'Awaiter,
+ // mapper: 'TResult1 -> 'TResult2
+ // ) : CancellableTaskResultBuilderBaseCode<_, _, _, _> =
+ // this.Bind((fun ct -> getAwaiterT ct), (fun v -> this.Return(mapper v)))
+
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
+ []
+ static member inline BindDynamic
+ (
+ sm:
+ byref>>,
+ awaiter: 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : bool =
+ sm.Data.ThrowIfCancellationRequested()
+ let mutable awaiter = awaiter
+
+ let cont =
+ (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, 'Builder>(fun
+ sm ->
+ let result = Awaiter.GetResult awaiter
+
+ (continuation result).Invoke(&sm)
+ ))
+
+ // shortcut to continue immediately
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <-
+ (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+
+ /// Creates A CancellableTask that runs computation, and when
+ /// computation generates a result T, runs binder res.
+ ///
+ /// A cancellation check is performed when the computation is executed.
+ ///
+ /// The existence of this method permits the use of let! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The computation to provide an unbound result.
+ /// The function to bind the result of computation.
+ ///
+ /// A CancellableTask that performs a monadic bind on the result
+ /// of computation.
+ []
+ member inline _.Bind
+ (
+ awaiterT: 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> =
+
+ CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm ->
+ if __useResumableCode then
+ //-- RESUMABLE CODE START
+ sm.Data.ThrowIfCancellationRequested()
+ // Get an awaiter from the Awaiter
+ let mutable awaiter = awaiterT
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ // This will yield with __stack_yield_fin = false
+ // This will resume with __stack_yield_fin = true
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+
+ (continuation result).Invoke(&sm)
+ else
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
+
+ false
+ else
+ CancellableTaskResultBuilderBase.BindDynamic(&sm, awaiterT, continuation)
+ //-- RESUMABLE CODE END
+ )
+
+ /// Delegates to the input computation.
+ ///
+ /// The existence of this method permits the use of return! in the
+ /// task { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ ///
+ /// The input computation.
+ []
+ member inline this.ReturnFrom
+ (awaiterT: 'Awaiter)
+ : CancellableTaskResultBuilderBaseCode<_, _, _, 'Builder> =
+ this.Bind(awaiterT = awaiterT, continuation = (fun v -> this.Return v))
+
+ // []
+ // member inline this.BindReturn
+ // (
+ // awaiterT: 'Awaiter,
+ // [] mapper: 'a -> 'TResult2
+ // ) : CancellableTaskResultBuilderBaseCode<'TResult2, 'TResult2, 'Error, 'Builder> =
+ // this.Bind(awaiterT = awaiterT, continuation = (fun v -> this.Return(mapper v)))
+
+
+ ///
+ []
+ module LowPriority =
+ // Low priority extensions
+ type CancellableTaskResultBuilderBase with
+
+ // ///
+ // /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ // ///
+ // []
+ // static member inline BindDynamic
+ // (
+ // sm:
+ // byref>>,
+ // [] getAwaiter: CancellationToken -> 'Awaiter,
+ // continuation:
+ // ('TResult1
+ // -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ // ) : bool =
+ // sm.Data.ThrowIfCancellationRequested()
+
+ // let mutable awaiter = getAwaiter sm.Data.CancellationToken
+
+ // let cont =
+ // (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, _>(fun sm ->
+ // let result = Awaiter.GetResult awaiter
+
+ // match result with
+ // | Ok result -> (continuation result).Invoke(&sm)
+ // | Error e ->
+ // sm.Data.Result <- Error e
+ // true
+ // ))
+
+ // // shortcut to continue immediately
+ // if Awaiter.IsCompleted awaiter then
+ // cont.Invoke(&sm)
+ // else
+ // sm.ResumptionDynamicInfo.ResumptionData <-
+ // (awaiter :> ICriticalNotifyCompletion)
+
+ // sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ // false
+
+ // /// Creates A CancellableTask that runs computation, and when
+ // /// computation generates a result T, runs binder res.
+ // ///
+ // /// A cancellation check is performed when the computation is executed.
+ // ///
+ // /// The existence of this method permits the use of let! in the
+ // /// cancellableTask { ... } computation expression syntax.
+ // ///
+ // /// The computation to provide an unbound result.
+ // /// The function to bind the result of computation.
+ // ///
+ // /// A CancellableTask that performs a monadic bind on the result
+ // /// of computation.
+ // []
+ // member inline _.Bind
+ // (
+ // [] getAwaiterTResult: CancellationToken -> 'Awaiter,
+ // continuation:
+ // ('TResult1
+ // -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ // ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> =
+
+ // CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm ->
+ // if __useResumableCode then
+ // //-- RESUMABLE CODE START
+ // sm.Data.ThrowIfCancellationRequested()
+ // // Get an awaiter from the Awaiter
+ // let mutable awaiter = getAwaiterTResult sm.Data.CancellationToken
+
+ // let mutable __stack_fin = true
+
+ // if not (Awaiter.IsCompleted awaiter) then
+ // // This will yield with __stack_yield_fin = false
+ // // This will resume with __stack_yield_fin = true
+ // let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ // __stack_fin <- __stack_yield_fin
+
+ // if __stack_fin then
+ // let result = Awaiter.GetResult awaiter
+
+ // match result with
+ // | Ok result -> (continuation result).Invoke(&sm)
+ // | Error e ->
+ // sm.Data.Result <- Error e
+ // true
+ // else
+ // let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ // MethodBuilder.AwaitUnsafeOnCompleted(
+ // &sm.Data.MethodBuilder,
+ // &awaiter,
+ // &sm
+ // )
+
+ // false
+ // else
+ // CancellableTaskResultBuilderBase.BindDynamic(
+ // &sm,
+ // getAwaiterTResult,
+ // continuation
+ // )
+ // //-- RESUMABLE CODE END
+ // )
+
+
+ /// Delegates to the input computation.
+ ///
+ /// The existence of this method permits the use of return! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ ///
+ /// The input computation.
+ []
+ member inline this.ReturnFrom
+ ([] getAwaiterTResult: CancellationToken -> 'Awaiter)
+ =
+ this.Bind(
+ getAwaiterTResult = (fun ct -> getAwaiterTResult ct),
+ continuation = (fun v -> this.Return v)
+ )
+
+
+ // []
+ // member inline this.BindReturn
+ // (
+ // [] getAwaiterTResult: CancellationToken -> 'Awaiter,
+ // mapper: 'TResult1 -> 'TResult2
+ // ) : CancellableTaskResultBuilderBaseCode<_, _, _, _> =
+ // this.Bind((fun ct -> getAwaiterTResult ct), (fun v -> this.Return(mapper v)))
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a CancellationToken -> 'Awaitable into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ []
+ member inline _.Source<'Awaitable, 'TResult1, 'Awaiter, 'TOverall
+ when Awaitable<'Awaitable, 'Awaiter, 'TResult1>>
+ ([] cancellableAwaiter: CancellationToken -> 'Awaiter)
+ : CancellationToken -> 'Awaiter =
+ (fun ct -> cancellableAwaiter ct)
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a CancellationToken -> 'Awaitable into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ []
+ member inline _.Source<'Awaitable, 'TResult1, 'Awaiter, 'TOverall
+ when Awaitable<'Awaitable, 'Awaiter, 'TResult1>>
+ ([] cancellableAwaitable: CancellationToken -> 'Awaitable)
+ : CancellationToken -> 'Awaiter =
+ (fun ct -> Awaitable.GetAwaiter(cancellableAwaitable ct))
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a unit -> 'Awaitable into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ []
+ member inline _.Source<'Awaitable, 'TResult1, 'Awaiter, 'TOverall
+ when Awaitable<'Awaitable, 'Awaiter, 'TResult1>>
+ ([] coldAwaitable: unit -> 'Awaitable)
+ : CancellationToken -> 'Awaiter =
+ (fun ct -> Awaitable.GetAwaiter(coldAwaitable ()))
+
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
+ []
+ static member inline BindDynamic
+ (
+ sm:
+ byref>>,
+ awaiter: 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : bool =
+ sm.Data.ThrowIfCancellationRequested()
+ let mutable awaiter = awaiter
+
+ let cont =
+ (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, 'Builder>(fun
+ sm ->
+ let result = Awaiter.GetResult awaiter
+
+ match result with
+ | Ok result -> (continuation result).Invoke(&sm)
+ | Error e ->
+ sm.Data.Result <- Error e
+ true
+ ))
+
+ // shortcut to continue immediately
+ if Awaiter.IsCompleted awaiter then
+ cont.Invoke(&sm)
+ else
+ sm.ResumptionDynamicInfo.ResumptionData <-
+ (awaiter :> ICriticalNotifyCompletion)
+
+ sm.ResumptionDynamicInfo.ResumptionFunc <- cont
+ false
+
+ /// Creates A CancellableTask that runs computation, and when
+ /// computation generates a result T, runs binder res.
+ ///
+ /// A cancellation check is performed when the computation is executed.
+ ///
+ /// The existence of this method permits the use of let! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The computation to provide an unbound result.
+ /// The function to bind the result of computation.
+ ///
+ /// A CancellableTask that performs a monadic bind on the result
+ /// of computation.
+ []
+ member inline _.Bind
+ (
+ awaiterTResult: 'Awaiter,
+ continuation:
+ ('TResult1
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>)
+ ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> =
+
+ CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm ->
+ if __useResumableCode then
+ //-- RESUMABLE CODE START
+ sm.Data.ThrowIfCancellationRequested()
+ // Get an awaiter from the Awaiter
+ let mutable awaiter = awaiterTResult
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ // This will yield with __stack_yield_fin = false
+ // This will resume with __stack_yield_fin = true
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+
+ match result with
+ | Ok result -> (continuation result).Invoke(&sm)
+ | Error e ->
+ sm.Data.Result <- Error e
+ true
+ else
+ let mutable awaiter = awaiter :> ICriticalNotifyCompletion
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
+
+ false
+ else
+ CancellableTaskResultBuilderBase.BindDynamic(
+ &sm,
+ awaiterTResult,
+ continuation
+ )
+ //-- RESUMABLE CODE END
+ )
+
+ /// Delegates to the input computation.
+ ///
+ /// The existence of this method permits the use of return! in the
+ /// task { ... } computation expression syntax.
+ ///
+ /// The input computation.
+ ///
+ /// The input computation.
+ []
+ member inline this.ReturnFrom
+ (awaiterTResult: 'Awaiter)
+ : CancellableTaskResultBuilderBaseCode<_, _, _, 'Builder> =
+ this.Bind(awaiterTResult = awaiterTResult, continuation = (fun v -> this.Return v))
+
+ // []
+ // member inline this.BindReturn
+ // (
+ // awaiterTResult: 'Awaiter,
+ // [] mapper: 'a -> 'TResult2
+ // ) : CancellableTaskResultBuilderBaseCode<'TResult2, 'TResult2, 'Error, 'Builder> =
+ // this.Bind(
+ // awaiterTResult = awaiterTResult,
+ // continuation = (fun v -> this.Return(mapper v))
+ // )
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This is the identify function.
+ ///
+ /// 'Awaiter
+ []
+ member inline _.Source<'TResult1, 'TResult2, 'Awaiter, 'TOverall
+ when Awaiter<'Awaiter, 'TResult1>>
+ (awaiter: 'Awaiter)
+ : 'Awaiter =
+ awaiter
+
+
+ /// Allows the computation expression to turn other types into 'Awaiter
+ ///
+ /// This turns a ^Awaitable into a 'Awaiter.
+ ///
+ /// 'Awaiter
+ []
+ member inline _.Source<'Awaitable, 'TResult1, 'TResult2, 'Awaiter, 'TOverall
+ when Awaitable<'Awaitable, 'Awaiter, 'TResult1>>
+ (task: 'Awaitable)
+ : 'Awaiter =
+ Awaitable.GetAwaiter task
+
+
+ /// Creates A CancellableTask that runs binder(resource).
+ /// The action resource.Dispose() is executed as this computation yields its result
+ /// or if the CancellableTask exits by an exception or by cancellation.
+ ///
+ ///
+ ///
+ /// The existence of this method permits the use of use and use! in the
+ /// cancellableTask { ... } computation expression syntax.
+ ///
+ /// The resource to be used and disposed.
+ /// The function that takes the resource and returns an asynchronous
+ /// computation.
+ ///
+ /// A CancellableTask that binds and eventually disposes resource.
+ ///
+ member inline _.Using
+ (
+ resource: #IDisposable,
+ binder:
+ #IDisposable
+ -> CancellableTaskResultBuilderBaseCode<'TOverall, 'T, 'Error, 'Builder>
+ ) =
+ ResumableCode.Using(resource, binder)
+
+
+ /// Allows the computation expression to turn other types into other types
+ ///
+ /// This is the identify function for For binds.
+ ///
+ /// IEnumerable
+ member inline _.Source(s: #seq<_>) : #seq<_> = s
+
+
+ []
+ module MedHighPriority =
+
+ type CancellableTaskResultBuilderBase with
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a Task<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// 'Awaiter
+ member inline _.Source(taskAwaiter: TaskAwaiter<'T>) : Awaiter, 'T> =
+ taskAwaiter
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a Task<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// 'Awaiter
+ member inline _.Source(taskT: Task<'T>) : Awaiter, 'T> =
+ Awaitable.GetTaskAwaiter taskT
+
+
+ member inline _.Source
+ (cancellableTask: CancellationToken -> Task<_>)
+ : CancellationToken -> Awaiter, _> =
+ fun ct -> Awaitable.GetTaskAwaiter(cancellableTask ct)
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a Async<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline this.Source(computation: Async<'T>) =
+ this.Source(Async.AsCancellableTask(computation))
+
+
+ ///
+ []
+ module HighPriority =
+
+
+ type Microsoft.FSharp.Control.Async with
+
+ static member inline AwaitCancellableTaskResult
+ ([] t: CancellableTaskResult<'T, 'Error>)
+ =
+ async {
+ let! ct = Async.CancellationToken
+
+ return!
+ t ct
+ |> Async.AwaitTask
+ }
+
+ static member inline AsCancellableTaskResult(computation: Async<'T>) =
+ fun ct -> Async.StartImmediateAsTask(computation, cancellationToken = ct)
+
+ type AsyncEx with
+
+ static member inline AwaitCancellableTaskResult
+ ([] t: CancellableTaskResult<'T, 'Error>)
+ =
+ async {
+ let! ct = Async.CancellationToken
+
+ return!
+ t ct
+ |> Async.AwaitTask
+ }
+
+ static member inline AsCancellableTaskResult(computation: Async<'T>) =
+ fun ct -> Async.StartImmediateAsTask(computation, cancellationToken = ct)
+
+
+ type AsyncResultCE.AsyncResultBuilder with
+
+ member inline this.Source
+ ([] t: CancellableTaskResult<'T, 'Error>)
+ : Async<_> =
+ Async.AwaitCancellableTaskResult t
+
+
+ // type AsyncEx with
+
+ // /// Return an asynchronous computation that will wait for the given task to complete and return
+ // /// its result.
+ // ///
+ // ///
+ // /// This is based on Async.Await overload (esp. AwaitTask without throwing AggregateException)
+ // ///
+ // static member inline AwaitCancellableTask
+ // ([] t: CancellationToken -> Task<'T>)
+ // =
+ // asyncEx {
+ // let! ct = Async.CancellationToken
+ // return! t ct
+ // }
+
+ // /// Return an asynchronous computation that will wait for the given task to complete and return
+ // /// its result.
+ // ///
+ // ///
+ // /// This is based on Async.Await overload (esp. AwaitTask without throwing AggregateException)
+ // ///
+ // static member inline AwaitCancellableTask
+ // ([] t: CancellationToken -> Task)
+ // =
+ // asyncEx {
+ // let! ct = Async.CancellationToken
+ // return! t ct
+ // }
+
+ // type Microsoft.FSharp.Control.Async with
+
+ // /// Return an asynchronous computation that will wait for the given task to complete and return
+ // /// its result.
+ // static member inline AwaitCancellableTask
+ // ([] t: CancellationToken -> Task<'T>)
+ // =
+ // async {
+ // let! ct = Async.CancellationToken
+
+ // return!
+ // t ct
+ // |> Async.AwaitTask
+ // }
+
+ // /// Return an asynchronous computation that will wait for the given task to complete and return
+ // /// its result.
+ // static member inline AwaitCancellableTask
+ // ([] t: CancellationToken -> Task)
+ // =
+ // async {
+ // let! ct = Async.CancellationToken
+
+ // return!
+ // t ct
+ // |> Async.AwaitTask
+ // }
+
+ // /// Runs an asynchronous computation, starting on the current operating system thread.
+ // static member inline AsCancellableTask
+ // (computation: Async<'T>)
+ // : CancellationToken -> Task<_> =
+ // fun ct -> Async.StartImmediateAsTask(computation, cancellationToken = ct)
+
+ // High priority extensions
+ type CancellableTaskResultBuilderBase with
+
+ /// Allows the computation expression to turn other types into other types
+ ///
+ /// This is the identify function for For binds.
+ ///
+ /// IEnumerable
+ member inline _.Source(s: #IAsyncEnumerable<_>) = s
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline _.Source
+ ([] task: unit -> TaskAwaiter<'T>)
+ : CancellationToken -> Awaiter, 'T> =
+ (fun (ct: CancellationToken) -> (task ()))
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline _.Source
+ ([] task: unit -> Task<'T>)
+ : CancellationToken -> Awaiter, 'T> =
+ (fun (ct: CancellationToken) -> Awaitable.GetTaskAwaiter(task ()))
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a CancellableTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline _.Source
+ ([] cancellableTaskAwaiter: CancellationToken -> TaskAwaiter<'T>)
+ : CancellationToken -> Awaiter, 'T> =
+ (fun ct -> (cancellableTaskAwaiter ct))
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a CancellableTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline _.Source
+ ([] task: CancellationToken -> Task<'T>)
+ : CancellationToken -> Awaiter, 'T> =
+ (fun ct -> Awaitable.GetTaskAwaiter(task ct))
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline _.Source(taskResult: TaskResult<'T, 'Error>) =
+ Awaitable.GetTaskAwaiter(taskResult)
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline this.Source
+ (asyncResult: Async>)
+ : CancellationToken -> TaskAwaiter> =
+ this.Source(Async.AsCancellableTask asyncResult)
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline this.Source
+ (asyncChoice: Async>)
+ : CancellationToken -> TaskAwaiter> =
+ this.Source(Async.map Result.ofChoice asyncChoice)
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline this.Source(result: Result<'T, 'Error>) =
+ this.Source(ValueTask<_>(result))
+
+
+ /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter
+ ///
+ /// This turns a ColdTask<'T> into a CancellationToken -> 'Awaiter.
+ ///
+ /// CancellationToken -> 'Awaiter
+ member inline this.Source(choice: Choice<'T, 'Error>) =
+ this.Source(ValueTask<_>(Result.ofChoice choice))
diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs
index c8648c2e..47b92aa5 100644
--- a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs
+++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs
@@ -1,6 +1,6 @@
namespace FsToolkit.ErrorHandling
-
+/// Contains methods to build CancellableTasks using the F# computation expression syntax
[]
module CancellableTaskResultCE =
@@ -13,262 +13,10 @@ module CancellableTaskResultCE =
open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
open Microsoft.FSharp.Collections
- open FsToolkit.ErrorHandling
open IcedTasks
- /// CancellationToken -> Task>
- type CancellableTaskResult<'T, 'Error> = CancellableTask>
-
-
- /// The extra data stored in ResumableStateMachine for tasks
- []
- type CancellableTaskResultStateMachineData<'T, 'Error> =
- []
- val mutable CancellationToken: CancellationToken
-
- []
- val mutable Result: Result<'T, 'Error>
-
- []
- val mutable MethodBuilder: CancellableTaskResultMethodBuilder<'T, 'Error>
-
-
- member inline this.IsResultError = Result.isError this.Result
- member inline this.IsTaskCompleted = this.MethodBuilder.Task.IsCompleted
-
- member inline this.ThrowIfCancellationRequested() =
- this.CancellationToken.ThrowIfCancellationRequested()
-
- and CancellableTaskResultMethodBuilder<'TOverall, 'Error> =
- AsyncTaskMethodBuilder>
-
- and CancellableTaskResultStateMachine<'TOverall, 'Error> =
- ResumableStateMachine>
-
- and CancellableTaskResultResumptionFunc<'TOverall, 'Error> =
- ResumptionFunc>
-
- and CancellableTaskResultResumptionDynamicInfo<'TOverall, 'Error> =
- ResumptionDynamicInfo>
-
- and CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- ResumableCode, 'T>
-
- type CancellableTaskResultBuilderBase() =
-
- member inline _.Delay
- (generator: unit -> CancellableTaskResultCode<'TOverall, 'Error, 'T>)
- : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- CancellableTaskResultCode<'TOverall, 'Error, 'T>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- (generator ()).Invoke(&sm)
- )
-
- /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression.
- []
- member inline _.Zero<'TOverall, 'Error>
- ()
- : CancellableTaskResultCode<'TOverall, 'Error, unit> =
- ResumableCode.Zero()
-
- member inline _.Return(value: 'T) : CancellableTaskResultCode<'T, 'Error, 'T> =
- CancellableTaskResultCode<'T, _, _>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- sm.Data.Result <- Ok value
- true
- )
-
-
- /// Chains together a step with its following step.
- /// Note that this requires that the first step has no result.
- /// This prevents constructs like `task { return 1; return 2; }`.
- member inline _.Combine
- (
- task1: CancellableTaskResultCode<'TOverall, 'Error, unit>,
- task2: CancellableTaskResultCode<'TOverall, 'Error, 'T>
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- ResumableCode.Combine(
- CancellableTaskResultCode(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- task1.Invoke(&sm)
- ),
- CancellableTaskResultCode<'TOverall, 'Error, 'T>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- if sm.Data.IsResultError then true else task2.Invoke(&sm)
- )
- )
-
-
- /// Builds a step that executes the body while the condition predicate is true.
- member inline _.While
- (
- [] condition: unit -> bool,
- body: CancellableTaskResultCode<'TOverall, 'Error, unit>
- ) : CancellableTaskResultCode<'TOverall, 'Error, unit> =
- let mutable keepGoing = true
-
- ResumableCode.While(
- (fun () ->
- keepGoing
- && condition ()
- ),
- CancellableTaskResultCode<_, _, _>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
-
- if sm.Data.IsResultError then
- keepGoing <- false
- sm.Data.MethodBuilder.SetResult sm.Data.Result
- true
- else
- body.Invoke(&sm)
- )
- )
-
- /// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function
- /// to retrieve the step, and in the continuation of the step (if any).
- member inline _.TryWith
- (
- computation: CancellableTaskResultCode<'TOverall, 'Error, 'T>,
- catchHandler: exn -> CancellableTaskResultCode<'TOverall, 'Error, 'T>
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- ResumableCode.TryWith(
- CancellableTaskResultCode(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- computation.Invoke(&sm)
- ),
- catchHandler
- )
-
- /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function
- /// to retrieve the step, and in the continuation of the step (if any).
- member inline _.TryFinally
- (
- computation: CancellableTaskResultCode<'TOverall, 'Error, 'T>,
- [] compensation: unit -> unit
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- ResumableCode.TryFinally(
-
- CancellableTaskResultCode(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- computation.Invoke(&sm)
- ),
- ResumableCode<_, _>(fun _ ->
- compensation ()
- true
- )
- )
-
- member inline this.For
- (
- sequence: seq<'T>,
- body: 'T -> CancellableTaskResultCode<'TOverall, 'Error, unit>
- ) : CancellableTaskResultCode<'TOverall, 'Error, unit> =
- ResumableCode.Using(
- sequence.GetEnumerator(),
- // ... and its body is a while loop that advances the enumerator and runs the body on each element.
- (fun e ->
- this.While(
- (fun () -> e.MoveNext()),
- CancellableTaskResultCode<'TOverall, 'Error, unit>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- (body e.Current).Invoke(&sm)
- )
- )
- )
- )
-
- member inline internal this.TryFinallyAsync
- (
- body: CancellableTaskResultCode<'TOverall, 'Error, 'T>,
- compensation: unit -> ValueTask
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- ResumableCode.TryFinallyAsync(
- body,
- ResumableCode<_, _>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
-
- if __useResumableCode then
- let mutable __stack_condition_fin = true
- let __stack_vtask = compensation ()
-
- if not __stack_vtask.IsCompleted then
- let mutable awaiter = __stack_vtask.GetAwaiter()
- let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
- __stack_condition_fin <- __stack_yield_fin
-
- if not __stack_condition_fin then
- sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
-
- __stack_condition_fin
- else
- let vtask = compensation ()
- let mutable awaiter = vtask.GetAwaiter()
-
- let cont =
- CancellableTaskResultResumptionFunc<'TOverall, 'Error>(fun sm ->
- awaiter.GetResult()
- |> ignore
-
- true
- )
-
- // shortcut to continue immediately
- if awaiter.IsCompleted then
- true
- else
- sm.ResumptionDynamicInfo.ResumptionData <-
- (awaiter :> ICriticalNotifyCompletion)
-
- sm.ResumptionDynamicInfo.ResumptionFunc <- cont
- false
- )
- )
-
- member inline this.Using<'Resource, 'TOverall, 'Error, 'T when 'Resource :> IAsyncDisposable>
- (
- resource: 'Resource,
- body: 'Resource -> CancellableTaskResultCode<'TOverall, 'Error, 'T>
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'T> =
- this.TryFinallyAsync(
- (fun sm -> (body resource).Invoke(&sm)),
- (fun () ->
- if not (isNull (box resource)) then
- resource.DisposeAsync()
- else
- ValueTask()
- )
- )
-
- member inline this.Source
- (ctr: CancellableTaskResult<'T, 'Error>)
- : CancellableTaskResult<'T, 'Error> =
- ctr
-
- member inline this.Source(xs: #seq<_>) = xs
-
- member inline _.Source(result: TaskResult<_, _>) : CancellableTaskResult<_, _> =
- cancellableTask { return! result }
-
- member inline _.Source(result: Async>) : CancellableTaskResult<_, _> =
- cancellableTask { return! result }
-
- member inline this.Source(result: Async>) : CancellableTaskResult<_, _> =
- result
- |> Async.map Result.ofChoice
- |> this.Source
-
- member inline _.Source(t: ValueTask>) : CancellableTaskResult<'T, 'Error> =
- cancellableTask { return! t }
-
- member inline _.Source(result: Result<_, _>) : CancellableTaskResult<_, _> =
- CancellableTask.singleton result
-
- member inline this.Source(result: Choice<_, _>) : CancellableTaskResult<_, _> =
- result
- |> Result.ofChoice
- |> this.Source
-
+ /// Contains methods to build CancellableTasks using the F# computation expression syntax
type CancellableTaskResultBuilder() =
inherit CancellableTaskResultBuilderBase()
@@ -279,17 +27,22 @@ module CancellableTaskResultCE =
// The executor stays constant throughout the execution, it wraps each step
// of the execution in a try/with. The resumption is changed at each step
// to represent the continuation of the computation.
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
static member inline RunDynamic
- (code: CancellableTaskResultCode<'T, 'Error, 'T>)
+ (code: CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, _>)
: CancellableTaskResult<'T, 'Error> =
- let mutable sm = CancellableTaskResultStateMachine<'T, 'Error>()
+ let mutable sm = CancellableTaskResultBuilderBaseStateMachine<'T, 'Error, _>()
let initialResumptionFunc =
- CancellableTaskResultResumptionFunc<'T, 'Error>(fun sm -> code.Invoke(&sm))
+ CancellableTaskResultBuilderBaseResumptionFunc<'T, 'Error, _>(fun sm ->
+ code.Invoke(&sm)
+ )
let resumptionInfo =
- { new CancellableTaskResultResumptionDynamicInfo<'T, 'Error>(initialResumptionFunc) with
+ { new CancellableTaskResultBuilderBaseResumptionDynamicInfo<'T, 'Error, _>(initialResumptionFunc) with
member info.MoveNext(sm) =
let mutable savedExn = null
@@ -297,29 +50,30 @@ module CancellableTaskResultCE =
sm.ResumptionDynamicInfo.ResumptionData <- null
let step = info.ResumptionFunc.Invoke(&sm)
- if sm.Data.IsTaskCompleted then
- ()
- elif step then
- sm.Data.MethodBuilder.SetResult(sm.Data.Result)
+ if step then
+ MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
else
let mutable awaiter =
sm.ResumptionDynamicInfo.ResumptionData
:?> ICriticalNotifyCompletion
assert not (isNull awaiter)
- sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
+
+ MethodBuilder.AwaitUnsafeOnCompleted(
+ &sm.Data.MethodBuilder,
+ &awaiter,
+ &sm
+ )
with exn ->
savedExn <- exn
// Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
match savedExn with
| null -> ()
- | exn ->
- // printfn "%A" exn
- sm.Data.MethodBuilder.SetException exn
+ | exn -> MethodBuilder.SetException(&sm.Data.MethodBuilder, exn)
member _.SetStateMachine(sm, state) =
- sm.Data.MethodBuilder.SetStateMachine(state)
+ MethodBuilder.SetStateMachine(&sm.Data.MethodBuilder, state)
}
fun (ct) ->
@@ -328,17 +82,17 @@ module CancellableTaskResultCE =
else
sm.Data.CancellationToken <- ct
sm.ResumptionDynamicInfo <- resumptionInfo
-
- sm.Data.MethodBuilder <- CancellableTaskResultMethodBuilder<'T, 'Error>.Create()
-
+ sm.Data.MethodBuilder <- AsyncTaskMethodBuilder>.Create()
sm.Data.MethodBuilder.Start(&sm)
sm.Data.MethodBuilder.Task
+
+ /// Hosts the task code in a state machine and starts the task.
member inline _.Run
- (code: CancellableTaskResultCode<'T, 'Error, 'T>)
+ (code: CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, _>)
: CancellableTaskResult<'T, 'Error> =
if __useResumableCode then
- __stateMachine, CancellableTaskResult<'T, 'Error>>
+ __stateMachine, CancellableTaskResult<'T, 'Error>>
(MoveNextMethodImpl<_>(fun sm ->
//-- RESUMABLE CODE START
__resumeAt sm.ResumptionPoint
@@ -347,23 +101,18 @@ module CancellableTaskResultCE =
try
let __stack_code_fin = code.Invoke(&sm)
- if
- __stack_code_fin
- && not sm.Data.IsTaskCompleted
- then
- sm.Data.MethodBuilder.SetResult(sm.Data.Result)
+ if __stack_code_fin then
+ MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
with exn ->
__stack_exn <- exn
// Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
match __stack_exn with
| null -> ()
- | exn ->
- // printfn "%A" exn
- sm.Data.MethodBuilder.SetException exn
+ | exn -> MethodBuilder.SetException(&sm.Data.MethodBuilder, exn)
//-- RESUMABLE CODE END
))
(SetStateMachineMethodImpl<_>(fun sm state ->
- sm.Data.MethodBuilder.SetStateMachine(state)
+ MethodBuilder.SetStateMachine(&sm.Data.MethodBuilder, state)
))
(AfterCode<_, _>(fun sm ->
let sm = sm
@@ -376,7 +125,7 @@ module CancellableTaskResultCE =
sm.Data.CancellationToken <- ct
sm.Data.MethodBuilder <-
- CancellableTaskResultMethodBuilder<'T, 'Error>.Create()
+ AsyncTaskMethodBuilder>.Create()
sm.Data.MethodBuilder.Start(&sm)
sm.Data.MethodBuilder.Task
@@ -384,12 +133,74 @@ module CancellableTaskResultCE =
else
CancellableTaskResultBuilder.RunDynamic(code)
+ /// Specify a Source of CancellationToken -> Task<_> on the real type to allow type inference to work
+ member inline _.Source
+ (x: CancellationToken -> Task<_>)
+ : CancellationToken -> Awaiter, _> =
+ fun ct -> Awaitable.GetTaskAwaiter(x ct)
+
+ // member inline this.MergeSources
+ // (
+ // [] left: CancellationToken -> 'Awaiter1,
+ // [] right: CancellationToken -> 'Awaiter2
+ // ) =
+ // this.Run(
+ // this.Bind(
+ // left,
+ // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR)))
+ // )
+ // )
+ // >> Awaitable.GetTaskAwaiter
+
+
+ // member inline this.MergeSources
+ // (
+ // left: 'Awaiter1,
+ // [] right: CancellationToken -> 'Awaiter2
+ // ) =
+ // this.Run(
+ // this.Bind(
+ // left,
+ // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR)))
+ // )
+ // )
+ // >> Awaitable.GetTaskAwaiter
+
+
+ // member inline this.MergeSources
+ // (
+ // [] left: CancellationToken -> 'Awaiter1,
+ // right: 'Awaiter2
+ // ) =
+ // this.Run(
+ // this.Bind(
+ // left,
+ // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR)))
+ // )
+ // )
+ // >> Awaitable.GetTaskAwaiter
+
+
+ // member inline this.MergeSources(left: 'Awaiter1, right: 'Awaiter2) =
+ // this.Run(
+ // this.Bind(
+ // left,
+ // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR)))
+ // )
+ // )
+ // >> Awaitable.GetTaskAwaiter
+
+
+ /// Contains methods to build CancellableTasks using the F# computation expression syntax
type BackgroundCancellableTaskResultBuilder() =
inherit CancellableTaskResultBuilderBase()
+ ///
+ /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code.
+ ///
static member inline RunDynamic
- (code: CancellableTaskResultCode<'T, 'Error, 'T>)
+ (code: CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, _>)
: CancellableTaskResult<'T, 'Error> =
// backgroundTask { .. } escapes to a background thread where necessary
// See spec of ConfigureAwait(false) at https://devblogs.microsoft.com/dotnet/configureawait-faq/
@@ -405,32 +216,34 @@ module CancellableTaskResultCE =
ct
)
- /// Same as CancellableTaskResultBuilder.Run except the start is inside Task.Run if necessary
+ ///
+ /// Hosts the task code in a state machine and starts the task, executing in the ThreadPool using Task.Run
+ ///
member inline _.Run
- (code: CancellableTaskResultCode<'T, 'Error, 'T>)
+ (code: CancellableTaskResultBuilderBaseCode<'T, 'T, 'Error, _>)
: CancellableTaskResult<'T, 'Error> =
if __useResumableCode then
- __stateMachine, CancellableTaskResult<'T, 'Error>>
+ __stateMachine, CancellableTaskResult<'T, 'Error>>
(MoveNextMethodImpl<_>(fun sm ->
//-- RESUMABLE CODE START
__resumeAt sm.ResumptionPoint
+ let mutable __stack_exn: Exception = null
try
let __stack_code_fin = code.Invoke(&sm)
- if
- __stack_code_fin
- && not sm.Data.IsTaskCompleted
- then
- sm.Data.MethodBuilder.SetResult(sm.Data.Result)
+ if __stack_code_fin then
+ MethodBuilder.SetResult(&sm.Data.MethodBuilder, sm.Data.Result)
with exn ->
-
- // printfn "%A" exn
- sm.Data.MethodBuilder.SetException exn
+ __stack_exn <- exn
+ // Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
+ match __stack_exn with
+ | null -> ()
+ | exn -> MethodBuilder.SetException(&sm.Data.MethodBuilder, exn)
//-- RESUMABLE CODE END
))
(SetStateMachineMethodImpl<_>(fun sm state ->
- sm.Data.MethodBuilder.SetStateMachine(state)
+ MethodBuilder.SetStateMachine(&sm.Data.MethodBuilder, state)
))
(AfterCode<_, CancellableTaskResult<'T, 'Error>>(fun sm ->
// backgroundTask { .. } escapes to a background thread where necessary
@@ -448,7 +261,7 @@ module CancellableTaskResultCE =
sm.Data.CancellationToken <- ct
sm.Data.MethodBuilder <-
- CancellableTaskResultMethodBuilder<'T, 'Error>.Create()
+ AsyncTaskMethodBuilder>.Create()
sm.Data.MethodBuilder.Start(&sm)
sm.Data.MethodBuilder.Task
@@ -465,7 +278,7 @@ module CancellableTaskResultCE =
sm.Data.CancellationToken <- ct
sm.Data.MethodBuilder <-
- CancellableTaskResultMethodBuilder<'T, 'Error>
+ AsyncTaskMethodBuilder>
.Create()
sm.Data.MethodBuilder.Start(&sm)
@@ -474,374 +287,176 @@ module CancellableTaskResultCE =
ct
)
))
+
else
BackgroundCancellableTaskResultBuilder.RunDynamic(code)
-
+ /// Contains the cancellableTask computation expression builder.
[]
module CancellableTaskResultBuilder =
+ ///
+ /// Builds a cancellableTask using computation expression syntax.
+ ///
let cancellableTaskResult = CancellableTaskResultBuilder()
- let backgroundCancellableTaskResult = BackgroundCancellableTaskResultBuilder()
-
- []
- module LowPriority =
- // Low priority extensions
- type CancellableTaskResultBuilderBase with
-
- []
- static member inline BindDynamic<'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error
- when ^Awaiter :> ICriticalNotifyCompletion
- and ^Awaiter: (member get_IsCompleted: unit -> bool)
- and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)>
- (
- sm:
- byref>>,
- getAwaiter: CancellationToken -> ^Awaiter,
- continuation:
- ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
- ) : bool =
- sm.Data.CancellationToken.ThrowIfCancellationRequested()
-
- let mutable awaiter = getAwaiter sm.Data.CancellationToken
-
- let cont =
- (CancellableTaskResultResumptionFunc<'TOverall, 'Error>(fun sm ->
- let result =
- (^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>) (awaiter))
-
- match result with
- | Ok result -> (continuation result).Invoke(&sm)
- | Error e ->
- sm.Data.Result <- Error e
- true
- ))
- // shortcut to continue immediately
- if (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
- cont.Invoke(&sm)
- else
- sm.ResumptionDynamicInfo.ResumptionData <-
- (awaiter :> ICriticalNotifyCompletion)
-
- sm.ResumptionDynamicInfo.ResumptionFunc <- cont
- false
-
- []
- member inline _.Bind<'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error
- when ^Awaiter :> ICriticalNotifyCompletion
- and ^Awaiter: (member get_IsCompleted: unit -> bool)
- and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)>
- (
- getAwaiter: CancellationToken -> ^Awaiter,
- continuation:
- ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'TResult2> =
-
- CancellableTaskResultCode<'TOverall, _, _>(fun sm ->
- if __useResumableCode then
- //-- RESUMABLE CODE START
- sm.Data.CancellationToken.ThrowIfCancellationRequested()
- // Get an awaiter from the awaitable
- let mutable awaiter = getAwaiter sm.Data.CancellationToken
-
- let mutable __stack_fin = true
-
- if not (^Awaiter: (member get_IsCompleted: unit -> bool) (awaiter)) then
- // This will yield with __stack_yield_fin = false
- // This will resume with __stack_yield_fin = true
- let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
- __stack_fin <- __stack_yield_fin
-
- if __stack_fin then
- let result =
- (^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>) (awaiter))
-
- match result with
- | Ok result -> (continuation result).Invoke(&sm)
- | Error e ->
- sm.Data.Result <- Error e
- true
- else
- sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
- false
- else
- CancellableTaskResultBuilderBase.BindDynamic<'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error>(
- &sm,
- getAwaiter,
- continuation
- )
- //-- RESUMABLE CODE END
- )
-
- []
- member inline this.ReturnFrom<'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error
- when ^Awaiter :> ICriticalNotifyCompletion
- and ^Awaiter: (member get_IsCompleted: unit -> bool)
- and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)>
- (getAwaiter: CancellationToken -> ^Awaiter)
- : CancellableTaskResultCode<'TResult1, 'Error, 'TResult1> =
-
- this.Bind(getAwaiter, (fun v -> this.Return v))
-
-
- []
- member inline _.Source<'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error
- when ^Awaiter :> ICriticalNotifyCompletion
- and ^Awaiter: (member get_IsCompleted: unit -> bool)
- and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)>
- (getAwaiter: CancellationToken -> ^Awaiter)
- : CancellationToken -> ^Awaiter =
- getAwaiter
-
- []
- member inline _.Source< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall, 'Error
- when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter)
- and ^Awaiter :> ICriticalNotifyCompletion
- and ^Awaiter: (member get_IsCompleted: unit -> bool)
- and ^Awaiter: (member GetResult: unit -> Result<'TResult1, 'Error>)>
- (task: ^TaskLike)
- : CancellationToken -> ^Awaiter =
- (fun (ct: CancellationToken) ->
- (^TaskLike: (member GetAwaiter: unit -> ^Awaiter) (task))
- )
-
- []
- member inline this.Source<'Awaitable, 'Awaiter, 'TResult, 'Error
- when Awaitable<'Awaitable, 'Awaiter, 'TResult>>
- (t: 'Awaitable)
- : CancellableTaskResult<'TResult, 'Error> =
-
- cancellableTask {
- let! r = t
- return Ok r
- }
-
-
- []
- member inline this.Source<'Awaitable, 'Awaiter, 'TResult, 'Error
- when Awaitable<'Awaitable, 'Awaiter, 'TResult>>
- (t: unit -> 'Awaitable)
- : CancellableTaskResult<'TResult, 'Error> =
-
- cancellableTask {
- let! r = t
- return Ok r
- }
-
-
- []
- member inline this.Source<'Awaitable, 'Awaiter, 'TResult, 'Error
- when Awaitable<'Awaitable, 'Awaiter, 'TResult>>
- (t: CancellationToken -> 'Awaitable)
- : CancellableTaskResult<'TResult, 'Error> =
-
- cancellableTask {
- let! r = t
- return Ok r
- }
-
- member inline _.Using<'Resource, 'TOverall, 'Error, 'T when 'Resource :> IDisposable>
- (
- resource: 'Resource,
- binder: 'Resource -> CancellableTaskResultCode<'TOverall, 'Error, 'T>
- ) =
- ResumableCode.Using(
- resource,
- fun resource ->
- CancellableTaskResultCode<'TOverall, 'Error, 'T>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- (binder resource).Invoke(&sm)
- )
- )
-
- []
- module HighPriority =
- type Microsoft.FSharp.Control.Async with
-
- static member inline AwaitCancellableTaskResult
- ([] t: CancellableTaskResult<'T, 'Error>)
- =
- async {
- let! ct = Async.CancellationToken
-
- return!
- t ct
- |> Async.AwaitTask
- }
-
- static member inline AsCancellableTaskResult(computation: Async<'T>) =
- fun ct -> Async.StartImmediateAsTask(computation, cancellationToken = ct)
+ ///
+ /// Builds a cancellableTask using computation expression syntax which switches to execute on a background thread if not already doing so.
+ ///
+ let backgroundCancellableTaskResult = BackgroundCancellableTaskResultBuilder()
- type CancellableTaskResultBuilderBase with
- member inline this.Bind
- (
- task: CancellableTaskResult<'TResult1, 'Error>,
- continuation:
- ('TResult1 -> CancellableTaskResultCode<'TOverall, 'Error, 'TResult2>)
- ) : CancellableTaskResultCode<'TOverall, 'Error, 'TResult2> =
- this.Bind((fun ct -> (task ct).GetAwaiter()), continuation)
+// ///
+// /// A set of extension methods making it possible to bind against in async computations.
+// ///
+// []
+// module AsyncExtensions =
- member inline this.ReturnFrom
- (task: CancellableTaskResult<'T, 'Error>)
- : CancellableTaskResultCode<'T, 'Error, 'T> =
- this.Bind(task, (fun v -> this.Return v))
+// type AsyncExBuilder with
+// member inline this.Source([] t: CancellableTask<'T>) : Async<'T> =
+// AsyncEx.AwaitCancellableTask t
- []
- module MediumPriority =
- open HighPriority
+// member inline this.Source([] t: CancellableTask) : Async =
+// AsyncEx.AwaitCancellableTask t
- type CancellableTaskResultBuilder with
+// type Microsoft.FSharp.Control.AsyncBuilder with
- member inline _.Source(t: Task<'T>) =
- cancellableTask {
- let! r = t
- return Ok r
- }
+// member inline this.Bind
+// (
+// [] t: CancellableTask<'T>,
+// [] binder: ('T -> Async<'U>)
+// ) : Async<'U> =
+// this.Bind(Async.AwaitCancellableTask t, binder)
- member inline _.Source(result: CancellableTask<'T>) =
- cancellableTask {
- let! r = result
- return Ok r
- }
+// member inline this.ReturnFrom([] t: CancellableTask<'T>) : Async<'T> =
+// this.ReturnFrom(Async.AwaitCancellableTask t)
- member inline _.Source(result: CancellableTask) : CancellableTaskResult =
- cancellableTask {
- let! r = result
- return Ok r
- }
+// member inline this.Bind
+// (
+// [] t: CancellableTask,
+// [] binder: (unit -> Async<'U>)
+// ) : Async<'U> =
+// this.Bind(Async.AwaitCancellableTask t, binder)
- member inline _.Source(result: ColdTask<_>) : CancellableTaskResult<_, _> =
- cancellableTask {
- let! r = result
- return Ok r
- }
+// member inline this.ReturnFrom([] t: CancellableTask) : Async =
+// this.ReturnFrom(Async.AwaitCancellableTask t)
- member inline _.Source(result: ColdTask) : CancellableTaskResult<_, _> =
- cancellableTask {
- let! r = result
- return Ok r
- }
+// // There is explicitly no Binds for `CancellableTasks` in `Microsoft.FSharp.Control.TaskBuilderBase`.
+// // You need to explicitly pass in a `CancellationToken`to start it, you can use `CancellationToken.None`.
+// // Reason is I don't want people to assume cancellation is happening without the caller being explicit about where the CancellationToken came from.
+// // Similar reasoning for `IcedTasks.ColdTasks.ColdTaskBuilderBase`.
- member inline _.Source(t: Async<'T>) : CancellableTaskResult<'T, 'Error> =
- cancellableTask {
- let! r = t
- return Ok r
- }
+// // Contains a set of standard functional helper function
+[]
+module CancellableTaskResult =
+ open System.Threading.Tasks
+ open System.Threading
+ open IcedTasks
- []
- module AsyncExtenions =
- type Microsoft.FSharp.Control.AsyncBuilder with
-
- member inline this.Bind
- (
- [] t: CancellableTaskResult<'T, 'Error>,
- [] binder: (_ -> Async<_>)
- ) : Async<_> =
- this.Bind(Async.AwaitCancellableTaskResult t, binder)
-
- member inline this.ReturnFrom([] t: CancellableTaskResult<'T, 'Error>) =
- this.ReturnFrom(Async.AwaitCancellableTaskResult t)
-
-
- type FsToolkit.ErrorHandling.AsyncResultCE.AsyncResultBuilder with
-
- member inline this.Source
- ([] t: CancellableTaskResult<'T, 'Error>)
- : Async<_> =
- Async.AwaitCancellableTaskResult t
-
- // There is explicitly no Binds for `CancellableTaskResults` in `Microsoft.FSharp.Control.TaskBuilderBase`.
- // You need to explicitly pass in a `CancellationToken`to start it, you can use `CancellationToken.None`.
- // Reason is I don't want people to assume cancellation is happening without the caller being explicit about where the CancellationToken came from.
-
- []
- module CancellableTaskResult =
- let getCancellationToken () : CancellableTaskResult =
- CancellableTaskResultBuilder.cancellableTaskResult.Run(
- CancellableTaskResultCode<_, 'Error, _>(fun sm ->
- sm.Data.Result <- Ok sm.Data.CancellationToken
- true
- )
- )
-
- /// Lifts an item to a CancellableTaskResult.
- /// The item to be the result of the CancellableTaskResult.
- /// A CancellableTaskResult with the item as the result.
- let inline singleton (item: 'item) : CancellableTaskResult<'item, 'Error> =
- fun _ -> Task.FromResult(Ok item)
-
-
- /// Allows chaining of CancellableTaskResult.
- /// The continuation.
- /// The value.
- /// The result of the binder.
- let inline bind
- ([] binder: 'input -> CancellableTaskResult<'output, 'error>)
- ([] cTask: CancellableTaskResult<'input, 'error>)
- =
- cancellableTaskResult {
- let! cResult = cTask
- return! binder cResult
- }
-
- /// Allows chaining of CancellableTaskResult.
- /// The continuation.
- /// The value.
- /// The result of the mapper wrapped in a CancellableTaskResult.
- let inline map
- ([] mapper: 'input -> 'output)
- ([] cTask: CancellableTaskResult<'input, 'error>)
- =
- cancellableTaskResult {
- let! cResult = cTask
- return mapper cResult
- }
-
- /// Allows chaining of CancellableTaskResult.
- /// A function wrapped in a CancellableTaskResult
- /// The value.
- /// The result of the applicable.
- let inline apply
- ([] applicable: CancellableTaskResult<'input -> 'output, 'error>)
- ([] cTask: CancellableTaskResult<'input, 'error>)
- =
- cancellableTaskResult {
- let! applier = applicable
- let! cResult = cTask
- return applier cResult
- }
-
- /// Takes two CancellableTaskResult, starts them serially in order of left to right, and returns a tuple of the pair.
- /// The left value.
- /// The right value.
- /// A tuple of the parameters passed in
- let inline zip
- ([] left: CancellableTaskResult<'left, 'error>)
- ([] right: CancellableTaskResult<'right, 'error>)
- =
- cancellableTaskResult {
- let! r1 = left
- let! r2 = right
- return r1, r2
- }
-
- /// Takes two CancellableTaskResult, starts them concurrently, and returns a tuple of the pair.
- /// The left value.
- /// The right value.
- /// A tuple of the parameters passed in.
- let inline parallelZip
- ([] left: CancellableTaskResult<'left, 'error>)
- ([] right: CancellableTaskResult<'right, 'error>)
- =
- cancellableTaskResult {
- let! ct = getCancellationToken ()
- let r1 = left ct
- let r2 = right ct
- let! r1 = r1
- let! r2 = r2
- return r1, r2
- }
+ /// Gets the default cancellation token for executing computations.
+ ///
+ /// The default CancellationToken.
+ ///
+ /// Cancellation and Exceptions
+ ///
+ ///
+ ///
+ /// use tokenSource = new CancellationTokenSource()
+ /// let primes = [ 2; 3; 5; 7; 11 ]
+ /// for i in primes do
+ /// let computation =
+ /// cancellableTask {
+ /// let! cancellationToken = CancellableTask.getCancellationToken()
+ /// do! Task.Delay(i * 1000, cancellationToken)
+ /// printfn $"{i}"
+ /// }
+ /// computation tokenSource.Token |> ignore
+ /// Thread.Sleep(6000)
+ /// tokenSource.Cancel()
+ /// printfn "Tasks Finished"
+ ///
+ /// This will print "2" 2 seconds from start, "3" 3 seconds from start, "5" 5 seconds from start, cease computation and then
+ /// followed by "Tasks Finished".
+ ///
+ let inline getCancellationToken () =
+ fun (ct: CancellationToken) -> ValueTask ct
+
+ /// Lifts an item to a CancellableTask.
+ /// The item to be the result of the CancellableTask.
+ /// A CancellableTask with the item as the result.
+ let inline singleton (item: 'item) : CancellableTaskResult<'item, 'Error> =
+ fun _ -> Task.FromResult(Ok item)
+
+
+ /// Allows chaining of CancellableTasks.
+ /// The continuation.
+ /// The value.
+ /// The result of the binder.
+ let inline bind
+ ([] binder: 'input -> CancellableTaskResult<'output, 'Error>)
+ ([] cTask: CancellableTaskResult<'input, 'Error>)
+ =
+ cancellableTaskResult {
+ let! cResult = cTask
+ return! binder cResult
+ }
+
+ /// Allows chaining of CancellableTasks.
+ /// The continuation.
+ /// The value.
+ /// The result of the mapper wrapped in a CancellableTasks.
+ let inline map
+ ([] mapper: 'input -> 'output)
+ ([] cTask: CancellableTaskResult<'input, 'Error>)
+ =
+ cancellableTaskResult {
+ let! cResult = cTask
+ return mapper cResult
+ }
+
+ /// Allows chaining of CancellableTasks.
+ /// A function wrapped in a CancellableTasks
+ /// The value.
+ /// The result of the applicable.
+ let inline apply
+ ([] applicable: CancellableTaskResult<'input -> 'output, 'Error>)
+ ([] cTask: CancellableTaskResult<'input, 'Error>)
+ =
+ cancellableTaskResult {
+ let! (applier: 'input -> 'output) = applicable
+ let! (cResult: 'input) = cTask
+ return applier cResult
+ }
+
+ /// Takes two CancellableTasks, starts them serially in order of left to right, and returns a tuple of the pair.
+ /// The left value.
+ /// The right value.
+ /// A tuple of the parameters passed in
+ let inline zip
+ ([] left: CancellableTaskResult<'left, 'Error>)
+ ([] right: CancellableTaskResult<'right, 'Error>)
+ =
+ cancellableTaskResult {
+ let! r1 = left
+ let! r2 = right
+ return r1, r2
+ }
+
+ /// Takes two CancellableTask, starts them concurrently, and returns a tuple of the pair.
+ /// The left value.
+ /// The right value.
+ /// A tuple of the parameters passed in.
+ let inline parallelZip
+ ([] left: CancellableTaskResult<'left, 'Error>)
+ ([] right: CancellableTaskResult<'right, 'Error>)
+ =
+ cancellableTask {
+ let! ct = getCancellationToken ()
+ let r1 = left ct
+ let r2 = right ct
+ let! r1 = r1
+ let! r2 = r2
+ return Result.zip r1 r2
+ }
diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs
index 208879fd..1ff8ba5e 100644
--- a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs
+++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs
@@ -1,6 +1,49 @@
namespace FsToolkit.ErrorHandling
+// What's going on here?
+//
+// F# method overload resolution has some weird quirks we're taking advantage of to allow
+// for binding (`let!/do!/return!`) many various types (Such as Task/Async/Result/Validation)
+// in a computation expression. .The gist is, any member methods attached to the type itself
+// (the Builder object) will be preferred above all else when selection overloads to resolve. It
+// will then use the the most recent Extension Methods that have been opened. The way we structure
+// these overloads is to provide the most "concrete" overloads first, and then the more generic
+// ones later. For example, `Validation` is defined as a `Result<'T, 'Error list>`, but we also
+// want to be able to bind to `Result` itself and create a list of errors from it. So we need to
+// have a `Validation` member method in a higher module, and then a `Result` member method
+// somewhere lower. Another example is `Task>` vs `Task<'T>`. We want to be able
+// to bind to both, so we need to have a `Task>` member method in a higher
+// module, and then a `Task<'T>` member method somewhere lower.
+
+// NoEagerConstraintApplication also changes behavior of SRTP methods, read the
+// TaskBuilder RFC for more info.
+
+// The reason we do AutoOpens here instead of using the attribute on the module itself
+// is because it may restrict how the implementation is relying on other sections, such as
+// The MediumPriority module may use something from the HighPriority module. If we put the
+// HighPriority module after the MediumPriority module it will fail to compile. So we don't want
+// the order of the code itself to determine the priority, this allows us to control that ordering
+// more explicitly.
+//
+// Additional readings:
+// - [F# Computation Expression Method Overload Resolution Ordering](https://gist.github.com/TheAngryByrd/c8b9c8ebcda3bb162f425bfb281d2e2b)
+// - [F# RFC FS-1097 - Task builder](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1097-task-builder.md#feature-noeagerconstraintapplicationattribute)
+// - ["Most concrete" tiebreaker for generic overloads](https://github.com/fsharp/fslang-suggestions/issues/905)
+
+
+// []
+// []
+// []
+// []
+// []
+// []
+// []
+// []
+// do ()
+
+
+/// Contains methods to build CancellableTasks using the F# computation expression syntax
[]
module CancellableTaskValidationCE =
@@ -13,327 +56,17 @@ module CancellableTaskValidationCE =
open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
open Microsoft.FSharp.Collections
- open FsToolkit.ErrorHandling
open IcedTasks
- /// CancellationToken -> Task>
- type CancellableTaskValidation<'T, 'Error> = CancellableTask>
- /// The extra data stored in ResumableStateMachine for tasks
- []
- type CancellableTaskValidationStateMachineData<'T, 'Error> =
- []
- val mutable CancellationToken: CancellationToken
+ /// CancellationToken -> Task>
+ type CancellableTaskValidation<'T, 'Error> = CancellableTask>
- []
- val mutable Result: Result<'T, 'Error list>
-
- []
- val mutable MethodBuilder: CancellableTaskValidationMethodBuilder<'T, 'Error>
-
- member inline this.IsResultError = Result.isError this.Result
-
- member inline this.ThrowIfCancellationRequested() =
- this.CancellationToken.ThrowIfCancellationRequested()
-
- and CancellableTaskValidationMethodBuilder<'TOverall, 'Error> =
- AsyncTaskMethodBuilder>
-
- and CancellableTaskValidationStateMachine<'TOverall, 'Error> =
- ResumableStateMachine>
-
- and CancellableTaskValidationResumptionFunc<'TOverall, 'Error> =
- ResumptionFunc>
-
- and CancellableTaskValidationResumptionDynamicInfo<'TOverall, 'Error> =
- ResumptionDynamicInfo>
-
- and CancellableTaskValidationCode<'TOverall, 'Error, 'T> =
- ResumableCode, 'T>
-
- type CancellableTaskValidationBuilderBase() =
-
- member inline _.Delay
- ([] generator:
- unit -> CancellableTaskValidationCode<'TOverall, 'Error, 'T>)
- : CancellableTaskValidationCode<'TOverall, 'Error, 'T> =
- CancellableTaskValidationCode<'TOverall, 'Error, 'T>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- (generator ()).Invoke(&sm)
- )
-
- /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression.
- []
- member inline _.Zero<'TOverall, 'Error>
- ()
- : CancellableTaskValidationCode<'TOverall, 'Error, unit> =
- ResumableCode.Zero()
-
- member inline _.Return(value: 'T) : CancellableTaskValidationCode<'T, 'Error, 'T> =
- CancellableTaskValidationCode<'T, _, _>(fun sm ->
- sm.Data.ThrowIfCancellationRequested()
- sm.Data.Result <- Ok value
- true
- )
-
-
- /// Chains together a step with its following step.
- /// Note that this requires that the first step has no result.
- /// This prevents constructs like `task { return 1; return 2; }`.
- member inline _.Combine
- (
- [] task1: CancellableTaskValidationCode<'TOverall, 'Error, unit>,
- [