diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..0bebc49a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "benchmarks", + "type": "coreclr", + "request": "launch", + "program": "${workspaceFolder}/benchmarks/bin/Release/net7.0/benchmarks.exe", + "args": [], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "console": "integratedTerminal", + "preLaunchTask": "build release", + "cwd": "${workspaceFolder}/benchmarks/bin/Release/net7.0/" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 360cd302..73af14d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,5 @@ { "editor.inlayHints.enabled": "off", - "FSharp.enableAdaptiveLspServer": true, "FSharp.enableMSBuildProjectGraph": true, "editor.formatOnSave": true, "FSharp.notifications.trace": false, @@ -8,6 +7,5 @@ "BoundModel.TypeCheck", "BackgroundCompiler." ], - "FSharp.fsac.conserveMemory": true, "FSharp.fsac.parallelReferenceResolution": false } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..9e0a7b39 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,18 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build release", + "type": "process", + "command": "dotnet", + "args": [ + "build", + "-c", + "Release", + "${workspaceFolder}/FsToolkit.ErrorHandling.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ] + } + ] +} diff --git a/benchmarks/Program.fs b/benchmarks/Program.fs index d94ef2b5..6a3054f6 100644 --- a/benchmarks/Program.fs +++ b/benchmarks/Program.fs @@ -3,23 +3,26 @@ open BenchmarkDotNet.Running open benchmarks open BenchmarkDotNet.Configs open BenchmarkDotNet.Jobs +open BenchmarkDotNet.Columns open BenchmarkDotNet.Environments +open BenchmarkDotNet.Reports open FsToolkit.ErrorHandling.Benchmarks open ApplicativeTests [] let main argv = + let cfg = - DefaultConfig - .Instance + DefaultConfig.Instance // .AddJob(Job.Default.WithRuntime(CoreRuntime.Core50)) - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core60)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core70)) + .AddColumn(StatisticColumn.P80, StatisticColumn.P95) + .WithSummaryStyle(SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend)) // BenchmarkRunner.Run() |> ignore // BenchmarkRunner.Run(cfg) |> ignore // BenchmarkRunner.Run() |> ignore - BenchmarkRunner.Run(cfg) + BenchmarkRunner.Run(cfg, argv) |> ignore - // 0 // return an integer exit code diff --git a/benchmarks/SeqTests.fs b/benchmarks/SeqTests.fs new file mode 100644 index 00000000..8c3ceba9 --- /dev/null +++ b/benchmarks/SeqTests.fs @@ -0,0 +1,341 @@ +module SeqTests + +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Order +open BenchmarkDotNet.Mathematics +open BenchmarkDotNet.Configs +open System.Threading +open System + +module sequenceResultMTests = + + // original used in v4.16.0 + module SeqCache = + + let sequenceResultM (xs: seq>) : Result<'t seq, 'e> = + let rec loop xs ts = + match Seq.tryHead xs with + | Some x -> + x + |> Result.bind (fun t -> loop (Seq.tail xs) (t :: ts)) + | None -> + Ok( + List.rev ts + |> List.toSeq + ) + + // Seq.cache prevents double evaluation in Seq.tail + loop (Seq.cache xs) [] + + module SeqFold = + + let traverseResultM' state (f: 'okInput -> Result<'okOutput, 'error>) xs = + let folder state x = + match state, f x with + | Error e, _ -> Error e + | Ok oks, Ok ok -> + Seq.singleton ok + |> Seq.append oks + |> Ok + | Ok _, Error e -> Error e + + Seq.fold folder state xs + |> Result.map Seq.rev + + let traverseResultM (f: 'okInput -> Result<'okOutput, 'error>) xs = + traverseResultM' (Ok Seq.empty) f xs + + let sequenceResultM xs = traverseResultM id xs + + module InlinedSeqFold = + + let inline traverseResultM' + state + ([] f: 'okInput -> Result<'okOutput, 'error>) + xs + = + let folder state x = + match state, f x with + | Error e, _ -> Error e + | Ok oks, Ok ok -> + Seq.singleton ok + |> Seq.append oks + |> Ok + | Ok _, Error e -> Error e + + Seq.fold folder state xs + |> Result.map Seq.rev + + let traverseResultM (f: 'okInput -> Result<'okOutput, 'error>) xs = + traverseResultM' (Ok Seq.empty) f xs + + let sequenceResultM xs = traverseResultM id xs + + module SeqUnfold = + + let traverseResultM' initialState (f: 'okInput -> Result<'okOutput, 'error>) xs = + (initialState, 0) + |> Seq.unfold (fun (state, i) -> + xs + |> Seq.tryItem i + |> Option.bind (fun x -> + match state, f x with + | Error _, _ -> None + | Ok oks, Ok ok -> + let newState = + Seq.singleton ok + |> Seq.append oks + |> Ok + + Some(newState, (newState, i + 1)) + | Ok _, Error e -> Some(Error e, (Error e, i + 1)) + ) + ) + |> Seq.last + + let traverseResultM f xs = traverseResultM' (Ok Seq.empty) f xs + let sequenceResultM xs = traverseResultM id xs + + module GetEnumerator = + + let traverseResultM' state (f: 'okInput -> Result<'okOutput, 'error>) (xs: seq<'okInput>) = + let mutable state = state + + let enumerator = xs.GetEnumerator() + + while Result.isOk state + && enumerator.MoveNext() do + match state, f enumerator.Current with + | Error _, _ -> () + | Ok oks, Ok ok -> state <- Ok(Seq.append oks (Seq.singleton ok)) + | Ok _, Error e -> state <- Error e + + state + + let traverseResultM f xs = traverseResultM' (Ok Seq.empty) f xs + let sequenceResultM xs = traverseResultM id xs + + module InlinedGetEnumerator = + + // adds an early exit upon encountering an error + let inline traverseResultM' + state + ([] f: 'okInput -> Result<'okOutput, 'error>) + (xs: seq<'okInput>) + = + let mutable state = state + let enumerator = xs.GetEnumerator() + + while Result.isOk state + && enumerator.MoveNext() do + match state, f enumerator.Current with + | Error e, _ -> state <- Error e + | Ok oks, Ok ok -> + state <- + Seq.singleton ok + |> Seq.append oks + |> Ok + | Ok _, Error e -> state <- Error e + + state + + let traverseResultM f xs = traverseResultM' (Ok Seq.empty) f xs + let sequenceResultM xs = traverseResultM id xs + + module SeqExpr = + + let inline traverseResultM' + state + ([] f: 'okInput -> Result<'okOutput, 'error>) + (xs: 'okInput seq) + = + match state with + | Error _ -> state + | Ok oks -> + use enumerator = xs.GetEnumerator() + + let rec loop oks = + if enumerator.MoveNext() then + match f enumerator.Current with + | Ok ok -> + loop ( + seq { + yield ok + yield! oks + } + ) + | Error e -> Error e + else + Ok(Seq.rev oks) + + loop oks + + let traverseResultM f xs = traverseResultM' (Ok Seq.empty) f xs + let sequenceResultM xs = traverseResultM id xs + + +[] +[] +[] +[] +[] +type SeqBenchmarks() = + + member _.thousandWithSleep = 1000u + + member _.fiveThousandWithSleep = 5_000u + + // for testing early escape performance + member _.GetPartialOkSeqWithSleep size = + seq { + for i in 1u .. size do + Thread.Sleep(TimeSpan.FromMicroseconds(1.0)) + if i = size / 2u then Error "error" else Ok i + } + + member _.thousand = 1_000u + + member _.million = 1_000_000u + + member _.GetPartialOkSeq size = + seq { + for i in 1u .. size do + if i = size / 2u then Error "error" else Ok i + } + + [] + [] + member this.seqCache() = + sequenceResultMTests.SeqCache.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.seqFoldSmall() = + sequenceResultMTests.SeqFold.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.inlineSeqFoldSmall() = + sequenceResultMTests.InlinedSeqFold.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.seqUnfoldSmall() = + sequenceResultMTests.SeqUnfold.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.getEnumeratorSmall() = + sequenceResultMTests.GetEnumerator.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.inlineGetEnumeratorSmall() = + sequenceResultMTests.InlinedGetEnumerator.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + [] + [] + member this.seqExpressionSmall() = + sequenceResultMTests.SeqExpr.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.thousandWithSleep + ) + + // made this baseline for this category since unfold and original were so unperformant for this size of data + [] + [] + member this.seqFoldLarge() = + sequenceResultMTests.SeqFold.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.fiveThousandWithSleep + ) + + [] + [] + member this.inlineSeqFoldLarge() = + sequenceResultMTests.InlinedSeqFold.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.fiveThousandWithSleep + ) + + [] + [] + member this.getEnumeratorLarge() = + sequenceResultMTests.GetEnumerator.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.fiveThousandWithSleep + ) + + [] + [] + member this.inlineGetEnumeratorLarge() = + sequenceResultMTests.InlinedGetEnumerator.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.fiveThousandWithSleep + ) + + [] + [] + member this.seqExpressionLarge() = + sequenceResultMTests.SeqExpr.sequenceResultM ( + this.GetPartialOkSeqWithSleep this.fiveThousandWithSleep + ) + + [] + [] + member this.SeqFuncsSmall() = + this.GetPartialOkSeq this.thousand + |> sequenceResultMTests.InlinedGetEnumerator.sequenceResultM + + [] + [] + member this.SeqExprSmall() = + this.GetPartialOkSeq this.thousand + |> sequenceResultMTests.SeqExpr.sequenceResultM + + [] + [] + member this.SeqFuncsSmallIter() = + this.GetPartialOkSeq this.thousand + |> sequenceResultMTests.GetEnumerator.sequenceResultM + |> Result.map (Seq.iter ignore) + + [] + [] + member this.SeqExprSmallIter() = + this.GetPartialOkSeq this.thousand + |> sequenceResultMTests.SeqExpr.sequenceResultM + |> Result.map (Seq.iter ignore) + + [] + [] + member this.SeqFuncsLarge() = + this.GetPartialOkSeq this.million + |> sequenceResultMTests.InlinedGetEnumerator.sequenceResultM + + [] + [] + member this.SeqExprLarge() = + this.GetPartialOkSeq this.million + |> sequenceResultMTests.SeqExpr.sequenceResultM + + [] + [] + member this.SeqFuncsLargeIter() = + this.GetPartialOkSeq this.million + |> sequenceResultMTests.GetEnumerator.sequenceResultM + |> Result.map (Seq.iter ignore) + + [] + [] + member this.SeqExprLargeIter() = + this.GetPartialOkSeq this.million + |> sequenceResultMTests.SeqExpr.sequenceResultM + |> Result.map (Seq.iter ignore) diff --git a/benchmarks/benchmarks.fsproj b/benchmarks/benchmarks.fsproj index 8c7050f0..99b4a122 100644 --- a/benchmarks/benchmarks.fsproj +++ b/benchmarks/benchmarks.fsproj @@ -18,6 +18,7 @@ true + diff --git a/gitbook/SUMMARY.md b/gitbook/SUMMARY.md index 7f912108..e9fa3062 100644 --- a/gitbook/SUMMARY.md +++ b/gitbook/SUMMARY.md @@ -25,6 +25,11 @@ * [sequenceResultM](list/sequenceResultM.md) * [traverseResultA](list/traverseResultA.md) * [sequenceResultA](list/sequenceResultA.md) + * Sequences + * [traverseResultM](seq/traverseResultM.md) + * [sequenceResultM](seq/sequenceResultM.md) + * [traverseResultA](seq/traverseResultA.md) + * [sequenceResultA](seq/sequenceResultA.md) * Transforms * [ofChoice](result/ofChoice.md) @@ -45,6 +50,11 @@ * [sequenceOptionM](option/sequenceOptionM.md) * [traverseVOptionM](option/traverseVOptionM.md) * [sequenceVOptionM](option/sequenceVOptionM.md) + * Sequences + * [traverseOptionM](seq/traverseOptionM.md) + * [sequenceOptionM](seq/sequenceOptionM.md) + * [traverseVOptionM](seq/traverseVOptionM.md) + * [sequenceVOptionM](seq/sequenceVOptionM.md) * Transforms * [ofNull](option/ofNull.md) * [ofPair](option/ofPair.md) @@ -89,6 +99,11 @@ * [sequenceAsyncResultM](list/sequenceAsyncResultM.md) * [traverseAsyncResultA](list/traverseAsyncResultA.md) * [sequenceAsyncResultA](list/sequenceAsyncResultA.md) + * Sequences + * [traverseAsyncResultM](seq/traverseAsyncResultM.md) + * [sequenceAsyncResultM](seq/sequenceAsyncResultM.md) + * [traverseAsyncResultA](seq/traverseAsyncResultA.md) + * [sequenceAsyncResultA](seq/sequenceAsyncResultA.md) * Transforms * [ofAsync](asyncResult/ofAsync.md) * [ofResult](asyncResult/ofResult.md) diff --git a/gitbook/seq/sequenceAsyncResultA.md b/gitbook/seq/sequenceAsyncResultA.md new file mode 100644 index 00000000..ace1eba5 --- /dev/null +++ b/gitbook/seq/sequenceAsyncResultA.md @@ -0,0 +1,20 @@ +## Seq.sequenceAsyncResultA + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +Async> seq -> Async> +``` + +Note that `sequence` is the same as `traverse id`. See also [Seq.traverseAsyncResultA](traverseAsyncResultA.md). + +This is applicative, collecting all errors. + +This is the same as [sequenceResultA](sequenceResultA.md) except that it uses `Async>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples + diff --git a/gitbook/seq/sequenceAsyncResultM.md b/gitbook/seq/sequenceAsyncResultM.md new file mode 100644 index 00000000..1ac5a60a --- /dev/null +++ b/gitbook/seq/sequenceAsyncResultM.md @@ -0,0 +1,19 @@ +## Seq.sequenceAsyncResultM + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +Async> seq -> Async> +``` + +Note that `sequence` is the same as `traverse id`. See also [Seq.traverseAsyncResultM](traverseAsyncResultM.md). + +This is monadic, stopping on the first error. + +This is the same as [sequenceResultM](sequenceResultM.md) except that it uses `Async>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/gitbook/seq/sequenceResultA.md b/gitbook/seq/sequenceResultA.md new file mode 100644 index 00000000..6364913a --- /dev/null +++ b/gitbook/seq/sequenceResultA.md @@ -0,0 +1,75 @@ +# Seq.sequenceResultA + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Result<'a, 'b> seq -> Result<'a seq, 'b seq> +``` + +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/). + +## Examples + +### Example 1 + +```fsharp +// string -> Result +let tryParseInt str = + match Int32.TryParse str with + | true, x -> Ok x + | false, _ -> + Error (sprintf "unable to parse '%s' to integer" str) + +["1"; "2"; "3"] +|> Seq.map tryParseInt +|> Seq.sequenceResultA +// 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"] +``` + +### 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 + else + let rec isPrime' (x : int) (i : int) = + if i * i > x then Ok true + elif x % i = 0 then Ok false + 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))' + +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 a = [2; 3; 4; 5;] |> checkIfAllPrime +// Ok false + +let a = [2; 3; 5;] |> checkIfAllPrime +// Ok true +``` diff --git a/gitbook/seq/sequenceResultM.md b/gitbook/seq/sequenceResultM.md new file mode 100644 index 00000000..4dddaa43 --- /dev/null +++ b/gitbook/seq/sequenceResultM.md @@ -0,0 +1,74 @@ +# Seq.sequenceResultM + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Result<'a, 'b> seq -> Result<'a seq, '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/). + +## Examples + +### Example 1 + +```fsharp +// string -> Result +let tryParseInt str = + match Int32.TryParse str with + | true, x -> Ok x + | false, _ -> + Error (sprintf "unable to parse '%s' to integer" str) + +["1"; "2"; "3"] +|> Seq.map tryParseInt +|> Seq.sequenceResultM +// Ok [1; 2; 3] + +["1"; "foo"; "3"; "bar"] +|> Seq.map tryParseInt +|> Seq.sequenceResultM +// Error "unable to parse 'foo' 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 + else + let rec isPrime' (x : int) (i : int) = + if i * i > x then Ok true + elif x % i = 0 then Ok false + else isPrime' x (i + 1) + isPrime' x 2 + +// int seq -> Result +let checkIfAllPrime (numbers : int 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))'; + +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 a = [2; 3; 4; 5;] |> checkIfAllPrime +// Ok false + +let a = [2; 3; 5;] |> checkIfAllPrime +// Ok true +``` diff --git a/gitbook/seq/sequenceTaskResultA.md b/gitbook/seq/sequenceTaskResultA.md new file mode 100644 index 00000000..df129763 --- /dev/null +++ b/gitbook/seq/sequenceTaskResultA.md @@ -0,0 +1,20 @@ +## Seq.sequenceTaskResultA + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +Task> seq -> Task> +``` + +Note that `sequence` is the same as `traverse id`. See also [Seq.traverseTaskResultA](traverseTaskResultA.md). + +This is applicative, collecting all errors. + +This is the same as [sequenceResultA](sequenceResultA.md) except that it uses `Task>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples + diff --git a/gitbook/seq/sequenceTaskResultM.md b/gitbook/seq/sequenceTaskResultM.md new file mode 100644 index 00000000..fa42c2c7 --- /dev/null +++ b/gitbook/seq/sequenceTaskResultM.md @@ -0,0 +1,19 @@ +## Seq.sequenceTaskResultM + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +Task> seq -> Task> +``` + +Note that `sequence` is the same as `traverse id`. See also [Seq.traverseTaskResultM](traverseTaskResultM.md). + +This is monadic, stopping on the first error. + +This is the same as [sequenceResultM](sequenceResultM.md) except that it uses `Task>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/gitbook/seq/traverseAsyncResultA.md b/gitbook/seq/traverseAsyncResultA.md new file mode 100644 index 00000000..6dddc83a --- /dev/null +++ b/gitbook/seq/traverseAsyncResultA.md @@ -0,0 +1,19 @@ +## Seq.traverseAsyncResultA + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +('a -> Async>) -> 'a seq -> Async> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceAsyncResultA](sequenceAsyncResultA.md). + +This is applicative, collecting all errors. + +This is the same as [traverseResultA](traverseResultA.md) except that it uses `Async>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/gitbook/seq/traverseAsyncResultM.md b/gitbook/seq/traverseAsyncResultM.md new file mode 100644 index 00000000..210bb227 --- /dev/null +++ b/gitbook/seq/traverseAsyncResultM.md @@ -0,0 +1,19 @@ +## Seq.traverseAsyncResultM + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +('a -> Async>) -> 'a seq -> Async> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceAsyncResultM](sequenceAsyncResultM.md). + +This is monadic, stopping on the first error. + +This is the same as [traverseResultM](traverseResultM.md) except that it uses `Async>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/gitbook/seq/traverseResultA.md b/gitbook/seq/traverseResultA.md new file mode 100644 index 00000000..d044b842 --- /dev/null +++ b/gitbook/seq/traverseResultA.md @@ -0,0 +1,72 @@ +# Seq.traverseResultA + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +('a -> Result<'b,'c>) -> 'a seq -> Result<'b seq, 'c seq> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceResultA](sequenceResultA.md). + +This is applicative, collecting all errors. Compare the example below with [traverseResultM](traverseResultM.md). + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples + +### Example 1 + +```fsharp +// string -> Result +let tryParseInt str = + match Int32.TryParse str with + | true, x -> Ok x + | false, _ -> + Error (sprintf "unable to parse '%s' to integer" str) + +["1"; "2"; "3"] +|> Seq.traverseResultA tryParseInt +// Ok [1; 2; 3] + +["1"; "foo"; "3"; "bar"] +|> Seq.traverseResultA tryParseInt +// 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 + else + let rec isPrime' (x : int) (i : int) = + if i * i > x then Ok true + elif x % i = 0 then Ok false + else isPrime' x (i + 1) + isPrime' x 2 + +// int seq -> Result +let checkIfAllPrime (numbers : int seq) = + numbers + |> Seq.traverseResultA isPrime // Result + |> Result.map (Seq.forall id) // shortened version of '|> Result.map (fun boolSeq -> boolSeq |> Seq.map (fun x -> x = true))' + +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 a = [2; 3; 4; 5;] |> checkIfAllPrime +// Ok false + +let a = [2; 3; 5;] |> checkIfAllPrime +// Ok true +``` diff --git a/gitbook/seq/traverseResultM.md b/gitbook/seq/traverseResultM.md new file mode 100644 index 00000000..12567942 --- /dev/null +++ b/gitbook/seq/traverseResultM.md @@ -0,0 +1,71 @@ +# Seq.traverseResultM + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +('a -> Result<'b,'c>) -> 'a seq -> Result<'b seq, 'c> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceResultM](sequenceResultM.md). + +This is monadic, stopping on the first error. Compare the example below with [traverseResultA](traverseResultA.md). + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples + +### Example 1 + +```fsharp +// string -> Result +let tryParseInt str = + match Int32.TryParse str with + | true, x -> Ok x + | false, _ -> + Error (sprintf "unable to parse '%s' to integer" str) + +["1"; "2"; "3"] +|> Seq.traverseResultM tryParseInt +// Ok [1; 2; 3] + +["1"; "foo"; "3"; "bar"] +|> Seq.traverseResultM tryParseInt +// Error "unable to parse 'foo' 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 + else + let rec isPrime' (x : int) (i : int) = + if i * i > x then Ok true + elif x % i = 0 then Ok false + else isPrime' x (i + 1) + isPrime' x 2 + +// int seq -> Result +let checkIfAllPrime (numbers : int seq) = + numbers + |> Seq.traverseResultM isPrime // Result + |> Result.map (Seq.forall id) // shortened version of '|> Result.map (fun boolSeq -> boolSeq |> Seq.map (fun x -> x = true))'; + +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 a = [2; 3; 4; 5;] |> checkIfAllPrime +// Ok false + +let a = [2; 3; 5;] |> checkIfAllPrime +// Ok true +``` diff --git a/gitbook/seq/traverseTaskResultA.md b/gitbook/seq/traverseTaskResultA.md new file mode 100644 index 00000000..26b105fa --- /dev/null +++ b/gitbook/seq/traverseTaskResultA.md @@ -0,0 +1,19 @@ +## Seq.traverseTaskResultA + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +('a -> Task>) -> 'a seq -> Task> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceTaskResultA](sequenceTaskResultA.md). + +This is applicative, collecting all errors. + +This is the same as [traverseResultA](traverseResultA.md) except that it uses `Task>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/gitbook/seq/traverseTaskResultM.md b/gitbook/seq/traverseTaskResultM.md new file mode 100644 index 00000000..2a52634e --- /dev/null +++ b/gitbook/seq/traverseTaskResultM.md @@ -0,0 +1,19 @@ +## Seq.traverseTaskResultM + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +``` +('a -> Task>) -> 'a seq -> Task> +``` + +Note that `traverse` is the same as `map >> sequence`. See also [Seq.sequenceTaskResultM](sequenceTaskResultM.md). + +This is monadic, stopping on the first error. + +This is the same as [traverseResultM](traverseResultM.md) except that it uses `Task>` instead of `Result<_,_>`. + +See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/). + +## Examples diff --git a/paket.dependencies b/paket.dependencies index 162993e7..313f1028 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -55,10 +55,10 @@ nuget Ply group Benchmarks source https://api.nuget.org/v3/index.json storage: none -nuget FSharp.Core ~> 7 -nuget BenchmarkDotNet 0.13.1 -nuget BenchmarkDotNet.Annotations 0.13.1 -nuget BenchmarkDotNet.Diagnostics.Windows 0.13.1 +nuget FSharp.Core +nuget BenchmarkDotNet +nuget BenchmarkDotNet.Annotations +nuget BenchmarkDotNet.Diagnostics.Windows // [ FAKE GROUP ] diff --git a/paket.lock b/paket.lock index 12d8f404..73301972 100644 --- a/paket.lock +++ b/paket.lock @@ -11,82 +11,79 @@ GROUP Benchmarks STORAGE: NONE NUGET remote: https://api.nuget.org/v3/index.json - BenchmarkDotNet (0.13.1) - BenchmarkDotNet.Annotations (>= 0.13.1) - restriction: >= netstandard2.0 - CommandLineParser (>= 2.4.3) - restriction: >= netstandard2.0 - Iced (>= 1.8) - restriction: >= netstandard2.0 - Microsoft.CodeAnalysis.CSharp (>= 2.10) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.NETCore.Client (>= 0.2.61701) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.Runtime (>= 1.1.126102) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.Tracing.TraceEvent (>= 2.0.61) - restriction: >= netstandard2.0 - Microsoft.DotNet.PlatformAbstractions (>= 2.1) - restriction: >= netstandard2.0 - Microsoft.Win32.Registry (>= 4.5) - restriction: >= netstandard2.0 - Perfolizer (>= 0.2.1) - restriction: >= netstandard2.0 - System.Management (>= 4.5) - restriction: >= netstandard2.0 - System.Reflection.Emit (>= 4.3) - restriction: >= netstandard2.0 - System.Reflection.Emit.Lightweight (>= 4.3) - restriction: >= netstandard2.0 - System.Threading.Tasks.Extensions (>= 4.5.2) - restriction: >= netstandard2.0 - System.ValueTuple (>= 4.5) - restriction: >= netstandard2.0 - BenchmarkDotNet.Annotations (0.13.1) + BenchmarkDotNet (0.14) + BenchmarkDotNet.Annotations (>= 0.14) - restriction: >= netstandard2.0 + CommandLineParser (>= 2.9.1) - restriction: >= netstandard2.0 + Gee.External.Capstone (>= 2.3) - restriction: >= netstandard2.0 + Iced (>= 1.17) - restriction: >= netstandard2.0 + Microsoft.CodeAnalysis.CSharp (>= 4.1) - restriction: >= netstandard2.0 + Microsoft.Diagnostics.Runtime (>= 2.2.332302) - restriction: >= netstandard2.0 + Microsoft.Diagnostics.Tracing.TraceEvent (>= 3.1.8) - restriction: >= netstandard2.0 + Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - restriction: >= netstandard2.0 + Microsoft.Win32.Registry (>= 5.0) - restriction: && (< net6.0) (>= netstandard2.0) + Perfolizer (0.3.17) - restriction: >= netstandard2.0 + System.Management (>= 5.0) - restriction: >= netstandard2.0 + System.Numerics.Vectors (>= 4.5) - restriction: && (< net6.0) (>= netstandard2.0) + System.Reflection.Emit (>= 4.7) - restriction: && (< net6.0) (>= netstandard2.0) + System.Reflection.Emit.Lightweight (>= 4.7) - restriction: && (< net6.0) (>= netstandard2.0) + System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: && (< net6.0) (>= netstandard2.0) + BenchmarkDotNet.Annotations (0.14) NETStandard.Library (>= 1.6.1) - restriction: && (>= netstandard1.0) (< netstandard2.0) - BenchmarkDotNet.Diagnostics.Windows (0.13.1) - BenchmarkDotNet (>= 0.13.1) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.Tracing.TraceEvent (>= 2.0.61) - restriction: >= netstandard2.0 + BenchmarkDotNet.Diagnostics.Windows (0.14) + BenchmarkDotNet (>= 0.14) - restriction: >= netstandard2.0 + Microsoft.Diagnostics.Tracing.TraceEvent (>= 3.1.8) - restriction: >= netstandard2.0 CommandLineParser (2.9.1) - restriction: >= netstandard2.0 - FSharp.Core (7.0.402) - Iced (1.20) - restriction: >= netstandard2.0 + FSharp.Core (8.0.400) + Gee.External.Capstone (2.3) - restriction: >= netstandard2.0 + Iced (1.21) - restriction: >= netstandard2.0 Microsoft.Bcl.AsyncInterfaces (8.0) - restriction: || (&& (>= net462) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (>= netstandard2.0) (< netstandard2.1)) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) Microsoft.CodeAnalysis.Analyzers (3.3.4) - restriction: >= netstandard2.0 - Microsoft.CodeAnalysis.Common (4.8) - restriction: >= netstandard2.0 + Microsoft.CodeAnalysis.Common (4.11) - restriction: >= netstandard2.0 Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) - restriction: >= netstandard2.0 - System.Collections.Immutable (>= 7.0) - restriction: >= netstandard2.0 - System.Memory (>= 4.5.5) - restriction: && (< net6.0) (>= netstandard2.0) - System.Reflection.Metadata (>= 7.0) - restriction: >= netstandard2.0 - System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: >= netstandard2.0 - System.Text.Encoding.CodePages (>= 7.0) - restriction: && (< net6.0) (>= netstandard2.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: && (< net6.0) (>= netstandard2.0) - Microsoft.CodeAnalysis.CSharp (4.8) - restriction: >= netstandard2.0 - Microsoft.CodeAnalysis.Common (4.8) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.NETCore.Client (0.2.452401) - restriction: >= netstandard2.0 + System.Buffers (>= 4.5.1) - restriction: && (< net7.0) (>= netstandard2.0) + System.Collections.Immutable (>= 8.0) - restriction: >= netstandard2.0 + System.Memory (>= 4.5.5) - restriction: && (< net7.0) (>= netstandard2.0) + System.Numerics.Vectors (>= 4.5) - restriction: && (< net7.0) (>= netstandard2.0) + System.Reflection.Metadata (>= 8.0) - restriction: >= netstandard2.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: && (< net7.0) (>= netstandard2.0) + System.Text.Encoding.CodePages (>= 7.0) - restriction: && (< net7.0) (>= netstandard2.0) + System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: && (< net7.0) (>= netstandard2.0) + Microsoft.CodeAnalysis.CSharp (4.11) - restriction: >= netstandard2.0 + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) - restriction: >= netstandard2.0 + Microsoft.CodeAnalysis.Common (4.11) - restriction: >= netstandard2.0 + System.Buffers (>= 4.5.1) - restriction: && (< net7.0) (>= netstandard2.0) + System.Collections.Immutable (>= 8.0) - restriction: >= netstandard2.0 + System.Memory (>= 4.5.5) - restriction: && (< net7.0) (>= netstandard2.0) + System.Numerics.Vectors (>= 4.5) - restriction: && (< net7.0) (>= netstandard2.0) + System.Reflection.Metadata (>= 8.0) - restriction: >= netstandard2.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: && (< net7.0) (>= netstandard2.0) + System.Text.Encoding.CodePages (>= 7.0) - restriction: && (< net7.0) (>= netstandard2.0) + System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: && (< net7.0) (>= netstandard2.0) + Microsoft.Diagnostics.NETCore.Client (0.2.532401) - restriction: >= netstandard2.0 Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: && (< net6.0) (>= netstandard2.0) - Microsoft.Extensions.Logging (>= 6.0) - restriction: >= netstandard2.0 + Microsoft.Extensions.Logging.Abstractions (>= 6.0.4) - restriction: >= netstandard2.0 System.Buffers (>= 4.5.1) - restriction: && (< net6.0) (>= netstandard2.0) - Microsoft.Diagnostics.Runtime (3.1.456101) - restriction: >= netstandard2.0 + Microsoft.Diagnostics.Runtime (3.1.512801) - restriction: >= netstandard2.0 Microsoft.Diagnostics.NETCore.Client (>= 0.2.410101) - restriction: >= netstandard2.0 - System.Collections.Immutable (>= 6.0) - restriction: >= netstandard2.0 + System.Collections.Immutable (>= 6.0) - restriction: && (< net6.0) (>= netstandard2.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: && (< net6.0) (>= netstandard2.0) + Microsoft.Diagnostics.Tracing.TraceEvent (3.1.15) - restriction: >= netstandard2.0 + Microsoft.Diagnostics.NETCore.Client (>= 0.2.510501) - restriction: >= netstandard2.0 + Microsoft.Win32.Registry (>= 5.0) - restriction: >= netstandard2.0 + System.Collections.Immutable (>= 8.0) - restriction: >= netstandard2.0 + System.Reflection.Metadata (>= 8.0) - restriction: >= netstandard2.0 + System.Reflection.TypeExtensions (>= 4.7) - restriction: >= netstandard2.0 System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: >= netstandard2.0 - Microsoft.Diagnostics.Tracing.TraceEvent (3.1.6) - restriction: >= netstandard2.0 - Microsoft.Win32.Registry (>= 4.4) - restriction: >= netstandard2.0 - System.Runtime.CompilerServices.Unsafe (>= 5.0) - restriction: >= netstandard2.0 Microsoft.DotNet.PlatformAbstractions (3.1.6) - restriction: >= netstandard2.0 System.Runtime.InteropServices.RuntimeInformation (>= 4.0) - restriction: || (>= net45) (&& (>= netstandard1.3) (< netstandard2.0)) - Microsoft.Extensions.DependencyInjection (8.0) - restriction: >= netstandard2.0 + Microsoft.Extensions.DependencyInjection.Abstractions (8.0.1) - restriction: >= netstandard2.0 Microsoft.Bcl.AsyncInterfaces (>= 8.0) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) - Microsoft.Extensions.DependencyInjection.Abstractions (8.0) - restriction: >= netstandard2.0 - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) - System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) - Microsoft.Extensions.Logging (8.0) - restriction: >= netstandard2.0 - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1)) - Microsoft.Extensions.DependencyInjection (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) - Microsoft.Extensions.Logging.Abstractions (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) - Microsoft.Extensions.Options (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) - System.Diagnostics.DiagnosticSource (>= 8.0) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.1)) (&& (>= netstandard2.0) (< netstandard2.1)) - System.ValueTuple (>= 4.5) - restriction: >= net462 - Microsoft.Extensions.Logging.Abstractions (8.0) - restriction: >= netstandard2.0 - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) + Microsoft.Extensions.Logging.Abstractions (8.0.1) - restriction: >= netstandard2.0 + Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.1) - restriction: || (>= net462) (>= netstandard2.0) System.Buffers (>= 4.5.1) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0)) System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net6.0) (>= netstandard2.0)) - Microsoft.Extensions.Options (8.0) - restriction: >= netstandard2.0 - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) - Microsoft.Extensions.Primitives (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) - System.ComponentModel.Annotations (>= 5.0) - restriction: || (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (&& (< net6.0) (>= netstandard2.1)) - System.ValueTuple (>= 4.5) - restriction: >= net462 - Microsoft.Extensions.Primitives (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)) Microsoft.NETCore.Platforms (7.0.4) - restriction: || (&& (>= monoandroid) (>= netcoreapp2.0) (< netstandard1.3)) (&& (>= monoandroid) (>= netcoreapp2.1) (< netstandard1.3)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.2) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.5) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.6) (< win8)) (&& (>= monotouch) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netcoreapp2.1)) (&& (>= net45) (< netstandard1.3)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.5) (< win8)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (>= net461) (>= netcoreapp2.0)) (&& (>= net461) (>= netcoreapp2.1)) (&& (>= net461) (< netstandard2.0)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinios)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinmac)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarintvos)) (&& (>= netcoreapp2.0) (< netcoreapp2.1) (>= xamarinwatchos)) (&& (>= netcoreapp2.0) (< netstandard2.0)) (&& (< netcoreapp2.0) (>= netcoreapp2.1)) (&& (>= netcoreapp2.1) (< netcoreapp3.0)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81)) (&& (>= netstandard1.1) (< portable-net45+win8+wpa81)) (&& (< netstandard1.1) (>= uap10.0) (< win8)) (&& (>= netstandard1.2) (< portable-net45+win8+wpa81)) (&& (< netstandard1.2) (>= uap10.0) (< win8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (< netstandard1.3) (< win8) (>= wpa81)) (&& (>= netstandard1.5) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= uap10.0)) (>= uap10.1) (>= wp8) Microsoft.NETCore.Targets (5.0) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.2) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.5) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.6) (< win8)) (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (< netstandard1.2) (>= netstandard1.5) (< win8)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.1) (< portable-net45+win8+wpa81)) (&& (< netstandard1.1) (>= uap10.0) (< win8)) (&& (>= netstandard1.2) (< portable-net45+win8+wpa81)) (&& (< netstandard1.2) (>= uap10.0) (< win8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.5) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< win81) (< wpa81)) Microsoft.Win32.Primitives (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) @@ -143,7 +140,7 @@ NUGET System.Threading.Timer (>= 4.3) - restriction: || (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) System.Xml.ReaderWriter (>= 4.3) - restriction: || (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) System.Xml.XDocument (>= 4.3) - restriction: || (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) - Perfolizer (0.3.5) - restriction: >= netstandard2.0 + Perfolizer (0.3.17) - restriction: >= netstandard2.0 System.Memory (>= 4.5.5) - restriction: && (>= netstandard2.0) (< netstandard2.1) runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) @@ -190,7 +187,7 @@ NUGET runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) System.AppContext (4.3) - restriction: || (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.6)) (&& (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) - System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard2.0) (>= xamarintvos)) (&& (>= netstandard2.0) (>= xamarinwatchos)) (>= xamarinios) (>= xamarinmac) + System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net6.0) (>= xamarinios)) (&& (< net6.0) (>= xamarinmac)) (&& (< net7.0) (>= netstandard2.0)) (&& (< net7.0) (>= xamarinios)) (&& (< net7.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) System.CodeDom (8.0) - restriction: >= netstandard2.0 System.Collections (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) @@ -210,7 +207,6 @@ NUGET 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.ComponentModel.Annotations (5.0) - restriction: || (&& (< net462) (>= netstandard2.0) (< netstandard2.1)) (&& (< net6.0) (>= netstandard2.1)) System.Console (4.3.1) - restriction: || (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net46) (>= netstandard1.3) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) Microsoft.NETCore.Targets (>= 1.1.2) - restriction: && (< monoandroid) (< monotouch) (< net46) (>= netstandard1.3) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -221,7 +217,7 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) Microsoft.NETCore.Targets (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) - System.Diagnostics.DiagnosticSource (8.0) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (>= net462) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.1)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard2.0) (< netstandard2.1)) + System.Diagnostics.DiagnosticSource (8.0.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) System.Diagnostics.Tools (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) Microsoft.NETCore.Targets (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -315,7 +311,7 @@ NUGET System.Threading (>= 4.3) - restriction: && (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Management (8.0) - restriction: >= netstandard2.0 System.CodeDom (>= 8.0) - restriction: >= 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)) (&& (< net6.0) (>= netstandard2.0)) (&& (>= netstandard2.0) (< netstandard2.1)) (&& (>= netstandard2.0) (>= uap10.1)) + 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)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net7.0) (>= netstandard2.0)) (&& (>= netstandard2.0) (< netstandard2.1)) (&& (>= 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 @@ -361,7 +357,7 @@ NUGET System.Net.Primitives (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net46) (>= netstandard1.3) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net46) (>= netstandard1.3) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Threading.Tasks (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net46) (>= netstandard1.3) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Numerics.Vectors (4.5) - restriction: || (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (&& (>= net461) (>= netstandard2.0)) + System.Numerics.Vectors (4.5) - restriction: || (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net461) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net7.0) (>= netstandard2.0)) System.ObjectModel (4.3) - restriction: || (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) System.Collections (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Diagnostics.Debug (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -374,10 +370,10 @@ NUGET System.IO (>= 4.3) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) System.Reflection.Primitives (>= 4.3) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) - System.Reflection.Emit (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) (>= netstandard2.0) + System.Reflection.Emit (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net6.0) (>= netstandard2.0)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= uap10.1) System.Reflection.Emit.ILGeneration (4.7) - restriction: || (&& (< monoandroid) (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) (&& (>= netstandard2.0) (>= uap10.1)) - System.Reflection.Emit.Lightweight (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) (>= netstandard2.0) + System.Reflection.Emit.Lightweight (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net6.0) (>= netstandard2.0)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< netstandard2.0) (< win8) (< wp8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< netstandard2.1) (< xamarintvos) (< xamarinwatchos)) (&& (< netstandard2.0) (>= wpa81)) (&& (>= portable-net45+win8+wp8+wpa81) (< portable-net45+wp8) (< win8)) (&& (< portable-net45+wp8) (>= win8)) (>= uap10.1) System.Reflection.Extensions (4.3) - restriction: || (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -391,20 +387,17 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) Microsoft.NETCore.Targets (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Reflection.TypeExtensions (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) - System.Reflection (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net46) (>= netstandard1.5) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.5) (< uap10.1)) - System.Resources.ResourceManager (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net46) (>= netstandard1.5) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.5) (< uap10.1)) - System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net46) (>= netstandard1.5) (< netstandard2.0) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net46) (>= netstandard1.3) (< netstandard1.5) (< uap10.1)) + System.Reflection.TypeExtensions (4.7) - restriction: || (&& (< monotouch) (< net45) (>= netstandard1.6) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) (>= netstandard2.0) System.Resources.ResourceManager (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) Microsoft.NETCore.Targets (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Globalization (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Reflection (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.0) (< win8) (< wp8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Runtime (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.2) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.5) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.6) (< win8)) (&& (< net45) (>= net46) (< netstandard1.3)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.5) (< win8)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.1) (< portable-net45+win8+wpa81)) (&& (< netstandard1.1) (>= uap10.0) (< win8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.5) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< win81) (< wpa81)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) + System.Runtime (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.2) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.4) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.5) (< win8)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard1.6) (< win8)) (&& (< net45) (>= net46) (< netstandard1.3)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.5) (< win8)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.1) (< portable-net45+win8+wpa81)) (&& (< netstandard1.1) (>= uap10.0) (< win8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.5) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< win81) (< wpa81)) 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.1)) (&& (>= net6.0) (< net7.0)) (>= netstandard2.0) (&& (< netstandard2.1) (>= xamarinios)) (&& (< netstandard2.1) (>= xamarinmac)) + System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< net7.0) (>= xamarinios)) (&& (< net7.0) (>= xamarinmac)) (>= netstandard2.0) System.Runtime.Extensions (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.6) (< portable-net45+win8+wpa81)) Microsoft.NETCore.Platforms (>= 1.1.1) - restriction: || (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< 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.3) (< win8) (< wp8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monotouch) (< net45) (>= netstandard1.5) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) @@ -433,7 +426,7 @@ NUGET System.Resources.ResourceManager (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard1.3) (< win8) (< wpa81)) System.Runtime.Extensions (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Security.AccessControl (6.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= netstandard2.0)) (>= netcoreapp2.1) (&& (>= netstandard2.0) (>= uap10.1)) (&& (>= netstandard2.0) (>= xamarintvos)) (&& (>= netstandard2.0) (>= xamarinwatchos)) (>= xamarinios) (>= xamarinmac) + System.Security.AccessControl (6.0.1) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< net6.0) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= 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)) System.Security.Principal.Windows (>= 5.0) - restriction: || (>= net461) (&& (< net6.0) (>= netstandard2.0)) System.Security.Cryptography.Algorithms (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= net461) (< netstandard1.2) (>= netstandard1.6)) (&& (< net45) (>= net461) (< netstandard1.3) (>= netstandard1.6)) (&& (< net45) (>= net461) (>= netstandard1.5) (< netstandard1.6)) (&& (< net45) (>= net461) (< netstandard1.5)) (&& (< net45) (>= net461) (>= netstandard1.6) (< netstandard2.0)) (&& (< net45) (>= net462) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (>= net462) (< netstandard1.5) (>= netstandard1.6)) (&& (< net45) (>= net47) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (>= net47) (< netstandard1.5) (>= netstandard1.6)) (&& (< net45) (>= net47) (>= netstandard1.6) (< netstandard2.0)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (>= net461) (< netstandard1.4)) (&& (>= net461) (< netstandard1.5) (>= uap10.0)) (&& (< netstandard1.4) (>= uap10.0)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -535,13 +528,13 @@ NUGET System.Security.Cryptography.Primitives (>= 4.3) - restriction: && (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Text.Encoding (>= 4.3) - restriction: && (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Threading (>= 4.3) - restriction: && (< monotouch) (< net46) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Security.Principal.Windows (5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= netcoreapp2.0)) (&& (>= net461) (>= netstandard2.0)) (>= netcoreapp2.1) (&& (>= netstandard2.0) (>= uap10.1)) (&& (>= netstandard2.0) (>= xamarintvos)) (&& (>= netstandard2.0) (>= xamarinwatchos)) (>= xamarinios) (>= xamarinmac) + System.Security.Principal.Windows (5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3) (>= netstandard2.0)) (&& (< monoandroid) (< net6.0) (>= netcoreapp2.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (>= 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 (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= net46) (< netstandard1.3)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.2) (>= netstandard1.5) (< win8)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (>= netstandard1.5) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) Microsoft.NETCore.Targets (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) - System.Text.Encoding.CodePages (8.0) - restriction: && (< net6.0) (>= netstandard2.0) + System.Text.Encoding.CodePages (8.0) - restriction: && (< net7.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.Encoding.Extensions (4.3) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) @@ -563,13 +556,12 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) Microsoft.NETCore.Targets (>= 1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) System.Runtime (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) - System.Threading.Tasks.Extensions (4.5.4) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (>= netstandard2.0) + System.Threading.Tasks.Extensions (4.5.4) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= net46) (< netstandard1.4)) (&& (>= net462) (>= netstandard2.0)) (&& (< net6.0) (>= netstandard2.0)) (&& (< net7.0) (>= netstandard2.0)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) (&& (>= 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) System.Threading.Timer (4.3) - restriction: || (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) Microsoft.NETCore.Platforms (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net451) (>= netstandard1.2) (< win81) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) Microsoft.NETCore.Targets (>= 1.1) - restriction: && (< monoandroid) (< monotouch) (< net451) (>= netstandard1.2) (< win81) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net451) (>= netstandard1.2) (< win81) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.ValueTuple (4.5) - restriction: >= netstandard2.0 System.Xml.ReaderWriter (4.3.1) - restriction: || (&& (< monoandroid) (< net45) (< netstandard1.2) (>= netstandard1.3) (< win8)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.4) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.5) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= net46) (< netstandard1.4)) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81) (< wp8)) (&& (>= netstandard1.3) (< portable-net45+win8+wpa81)) (&& (< netstandard1.3) (>= uap10.0) (< win8) (< wpa81)) (&& (< netstandard1.5) (>= uap10.0) (< uap10.1)) (&& (< netstandard1.5) (>= uap10.0) (< win8) (< wpa81)) System.Collections (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Diagnostics.Debug (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) diff --git a/src/FsToolkit.ErrorHandling/Seq.fs b/src/FsToolkit.ErrorHandling/Seq.fs index 8a3fe81f..89d47916 100644 --- a/src/FsToolkit.ErrorHandling/Seq.fs +++ b/src/FsToolkit.ErrorHandling/Seq.fs @@ -3,17 +3,364 @@ namespace FsToolkit.ErrorHandling [] module Seq = - let sequenceResultM (xs: seq>) : Result<'t seq, 'e> = - let rec loop xs ts = - match Seq.tryHead xs with - | Some x -> - x - |> Result.bind (fun t -> loop (Seq.tail xs) (t :: ts)) - | None -> - Ok( - List.rev ts - |> List.toSeq - ) - - // Seq.cache prevents double evaluation in Seq.tail - loop (Seq.cache xs) [] + /// + /// Applies a function to each element of a sequence and returns a single result + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// A result with the ok elements in a sequence or the first error occurring in the sequence + let inline traverseResultM' + state + ([] f: 'okInput -> Result<'okOutput, 'error>) + (xs: 'okInput seq) + = + match state with + | Error _ -> state + | Ok oks -> + use enumerator = xs.GetEnumerator() + + let rec loop oks = + if enumerator.MoveNext() then + match f enumerator.Current with + | Ok ok -> + loop ( + seq { + yield ok + yield! oks + } + ) + | Error e -> Error e + else + Ok(Seq.rev oks) + + loop oks + + /// + /// Applies a function to each element of a sequence and returns a single result + /// + /// The function to apply to each element + /// The input sequence + /// A result with the ok elements in a sequence or the first error occurring in the sequence + /// This function is equivalent to but applying and initial state of 'Seq.empty' + let traverseResultM f xs = traverseResultM' (Ok Seq.empty) f xs + + /// + /// Converts a sequence of results into a single result + /// + /// The input sequence + /// A result with the ok elements in a sequence or the first error occurring in the sequence + /// This function is equivalent to but auto-applying the 'id' function + let sequenceResultM xs = traverseResultM id xs + + /// + /// Applies a function to each element of a sequence and returns a single result + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// A result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + let inline traverseResultA' + state + ([] f: 'okInput -> Result<'okOutput, 'error>) + xs + = + let folder state x = + match state, f x with + | Error errors, Error e -> + Seq.append errors (Seq.singleton e) + |> Error + | Ok oks, Ok ok -> + Seq.append oks (Seq.singleton ok) + |> Ok + | Ok _, Error e -> + Seq.singleton e + |> Error + | Error _, Ok _ -> state + + Seq.fold folder state xs + + /// + /// Applies a function to each element of a sequence and returns a single result + /// + /// The function to apply to each element + /// The input sequence + /// A result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + /// This function is equivalent to but applying and initial state of 'Seq.empty' + let traverseResultA f xs = traverseResultA' (Ok Seq.empty) f xs + + /// + /// Converts a sequence of results into a single result + /// + /// The input sequence + /// A result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + /// This function is equivalent to but auto-applying the 'id' function + let sequenceResultA xs = traverseResultA id xs + + /// + /// Applies a function to each element of a sequence and returns a single async result + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// An async result with the ok elements in a sequence or the first error occurring in the sequence + let inline traverseAsyncResultM' + state + ([] f: 'okInput -> Async>) + (xs: 'okInput seq) + = + async { + match! state with + | Error _ -> return! state + | Ok oks -> + use enumerator = xs.GetEnumerator() + + let rec loop oks = + async { + if enumerator.MoveNext() then + match! f enumerator.Current with + | Ok ok -> + return! + loop ( + seq { + yield ok + yield! oks + } + ) + | Error e -> return Error e + else + return Ok(Seq.rev oks) + } + + return! loop oks + } + + /// + /// Applies a function to each element of a sequence and returns a single async result + /// + /// The function to apply to each element + /// The input sequence + /// An async result with the ok elements in a sequence or the first error occurring in the sequence + /// This function is equivalent to but applying and initial state of 'Seq.empty' + let traverseAsyncResultM f xs = + traverseAsyncResultM' (async { return Ok Seq.empty }) f xs + + /// + /// Converts a sequence of async results into a single async result + /// + /// The input sequence + /// An async result with the ok elements in a sequence or the first error occurring in the sequence + /// This function is equivalent to but auto-applying the 'id' function + let sequenceAsyncResultM xs = traverseAsyncResultM id xs + + /// + /// Applies a function to each element of a sequence and returns a single async result + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// An async result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + let inline traverseAsyncResultA' + state + ([] f: 'okInput -> Async>) + xs + = + let folder state x = + async { + let! state = state + let! result = f x + + return + match state, result with + | Error errors, Error e -> + Seq.append errors (Seq.singleton e) + |> Error + | Ok oks, Ok ok -> + Seq.append oks (Seq.singleton ok) + |> Ok + | Ok _, Error e -> + Seq.singleton e + |> Error + | Error _, Ok _ -> state + } + + Seq.fold folder state xs + + /// + /// Applies a function to each element of a sequence and returns a single async result + /// + /// The function to apply to each element + /// The input sequence + /// An async result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + /// This function is equivalent to but applying and initial state of 'Seq.empty' + let traverseAsyncResultA f xs = + traverseAsyncResultA' (async { return Ok Seq.empty }) f xs + + /// + /// Converts a sequence of async results into a single async result + /// + /// The input sequence + /// An async result with the ok elements in a sequence or a sequence of all errors occuring in the original sequence + /// This function is equivalent to but auto-applying the 'id' function + let sequenceAsyncResultA xs = traverseAsyncResultA id xs + + /// + /// Applies a function to each element of a sequence and returns a single option + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// An option containing Some sequence of elements or None if any of the function applications return None + let inline traverseOptionM' + state + ([] f: 'okInput -> 'okOutput option) + (xs: 'okInput seq) + = + match state with + | None -> state + | Some values -> + use enumerator = xs.GetEnumerator() + + let rec loop values = + if enumerator.MoveNext() then + match f enumerator.Current with + | Some value -> + loop ( + seq { + yield value + yield! values + } + ) + | None -> None + else + Some(Seq.rev values) + + loop values + + /// + /// Applies a function to each element of a sequence and returns a single option + /// + /// The function to apply to each element + /// The input sequence + /// An option containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but applying and initial state of 'Seq.empty' + let traverseOptionM f xs = traverseOptionM' (Some Seq.empty) f xs + + /// + /// Converts a sequence of options into a single option + /// + /// The input sequence + /// An option containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but auto-applying the 'id' function + let sequenceOptionM xs = traverseOptionM id xs + + /// + /// Applies a function to each element of a sequence and returns a single async option + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// An async option containing Some sequence of elements or None if any of the function applications return None + let inline traverseAsyncOptionM' + state + ([] f: 'okInput -> Async<'okOutput option>) + (xs: 'okInput seq) + = + async { + match! state with + | None -> return! state + | Some values -> + use enumerator = xs.GetEnumerator() + + let rec loop values = + async { + if enumerator.MoveNext() then + match! f enumerator.Current with + | Some value -> + return! + loop ( + seq { + yield value + yield! values + } + ) + | None -> return None + else + return Some(Seq.rev values) + } + + return! loop values + } + + /// + /// Applies a function to each element of a sequence and returns a single async option + /// + /// The function to apply to each element + /// The input sequence + /// An async option containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but applying and initial state of 'Async { return Some Seq.empty }' + let traverseAsyncOptionM f xs = + traverseAsyncOptionM' (async { return Some Seq.empty }) f xs + + /// + /// Converts a sequence of async options into a single async option + /// + /// The input sequence + /// An async option containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but auto-applying the 'id' function + let sequenceAsyncOptionM xs = traverseAsyncOptionM id xs + +#if !FABLE_COMPILER + + /// + /// Applies a function to each element of a sequence and returns a single voption + /// + /// The initial state + /// The function to apply to each element + /// The input sequence + /// A voption containing Some sequence of elements or None if any of the function applications return None + let inline traverseVOptionM' + state + ([] f: 'okInput -> 'okOutput voption) + (xs: 'okInput seq) + = + match state with + | ValueNone -> state + | ValueSome values -> + use enumerator = xs.GetEnumerator() + + let rec loop values = + if enumerator.MoveNext() then + match f enumerator.Current with + | ValueSome value -> + loop ( + seq { + yield value + yield! values + } + ) + | ValueNone -> ValueNone + else + ValueSome(Seq.rev values) + + loop values + + /// + /// Applies a function to each element of a sequence and returns a single voption + /// + /// The function to apply to each element + /// The input sequence + /// A voption containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but applying and initial state of 'ValueSome Seq.empty' + let traverseVOptionM f xs = + traverseVOptionM' (ValueSome Seq.empty) f xs + + /// + /// Converts a sequence of voptions into a single voption + /// + /// The input sequence + /// A voption containing Some sequence of elements or None if any of the function applications return None + /// This function is equivalent to but auto-applying the 'id' function + let sequenceVOptionM xs = traverseVOptionM id xs + +#endif diff --git a/tests/FsToolkit.ErrorHandling.Tests/Expect.fs b/tests/FsToolkit.ErrorHandling.Tests/Expect.fs index 2688982b..591259e0 100644 --- a/tests/FsToolkit.ErrorHandling.Tests/Expect.fs +++ b/tests/FsToolkit.ErrorHandling.Tests/Expect.fs @@ -42,12 +42,30 @@ module Expect = | Ok x -> Tests.failtestf "Expected Ok(%A), was Ok(%A)." v x | Error x -> Tests.failtestf "Expected Ok, was Error(%A)." x + let hasOkSeqValue v x = + match x with + | Ok x -> + if Seq.forall2 (fun a b -> a = b) v x then + () + else + Tests.failtestf "Expected Ok(%A), was Ok(%A)." v x + | Error x -> Tests.failtestf "Expected Ok, was Error(%A)." x + let hasSomeValue v x = match x with | Some x when x = v -> () | Some x -> Tests.failtestf "Expected Some(%A), was Some(%A)." v x | None -> Tests.failtestf "Expected Some, was None." + let hasSomeSeqValue v x = + match x with + | Some x -> + if Seq.forall2 (fun a b -> a = b) v x then + () + else + Tests.failtestf "Expected Some(%A), was Some(%A)." v x + | None -> Tests.failtestf "Expected Some, was None." + let hasNoneValue x = match x with | None -> () @@ -69,6 +87,12 @@ module Expect = hasOkValue v x } + let hasAsyncOkSeqValue v asyncX = + async { + let! x = asyncX + hasOkSeqValue v x + } + let hasAsyncErrorValue v asyncX = async { let! x = asyncX @@ -81,6 +105,12 @@ module Expect = hasSomeValue v x } + let hasAsyncSomeSeqValue v asyncX = + async { + let! x = asyncX + hasSomeSeqValue v x + } + let hasAsyncNoneValue asyncX = async { let! x = asyncX diff --git a/tests/FsToolkit.ErrorHandling.Tests/Seq.fs b/tests/FsToolkit.ErrorHandling.Tests/Seq.fs index 522b7041..2059337d 100644 --- a/tests/FsToolkit.ErrorHandling.Tests/Seq.fs +++ b/tests/FsToolkit.ErrorHandling.Tests/Seq.fs @@ -16,47 +16,117 @@ open TestHelpers open System open FsToolkit.ErrorHandling +let traverseResultMTests = + testList "Seq.traverseResultM Tests" [ + testCase "traverseResult with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } -let sequenceResultMTests = - testList "Seq.sequenceResultM Tests" [ - testCase "traverseResult with an empty sequence" + let expected = + Seq.map tweet tweets + |> Seq.toList + + let actual = Seq.traverseResultM Tweet.TryCreate tweets + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid tweets" + + testCase "traverseResultM with few invalid data" <| fun _ -> - let tweets = [] - let expected = Ok [] + let tweets = + seq { + "" + "Hello" + aLongerInvalidTweet + } + + let actual = Seq.traverseResultM Tweet.TryCreate tweets + + Expect.equal + actual + (Error emptyTweetErrMsg) + "traverse the sequence and return the first error" + ] + +let traverseOptionMTests = + testList "Seq.traverseOptionM Tests" [ + let tryTweetOption x = + match x with + | x when String.IsNullOrEmpty x -> None + | _ -> Some x + + testCase "traverseOption with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = Seq.toList tweets + let actual = Seq.traverseOptionM tryTweetOption tweets let actual = - Seq.sequenceResultM (Seq.map Tweet.TryCreate tweets) - |> Result.map Seq.toList + Expect.wantSome actual "Expected result to be Some" + |> Seq.toList - Expect.equal actual expected "Should have an empty list of valid tweets" + Expect.equal actual expected "Should have a sequence of valid tweets" + testCase "traverseOption with few invalid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + String.Empty + } + + let expected = None + let actual = Seq.traverseOptionM tryTweetOption tweets + + Expect.equal actual expected "traverse the sequence and return none" + ] + +let sequenceResultMTests = + testList "Seq.sequenceResultM Tests" [ testCase "traverseResult with a sequence of valid data" <| fun _ -> - let tweets = [ - "Hi" - "Hello" - "Hola" - ] + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } let expected = - List.map tweet tweets - |> Ok + Seq.map tweet tweets + |> Seq.toList + + let actual = Seq.sequenceResultM (Seq.map Tweet.TryCreate tweets) let actual = - Seq.sequenceResultM (Seq.map Tweet.TryCreate tweets) - |> Result.map Seq.toList + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList - Expect.equal actual expected "Should have a list of valid tweets" + Expect.equal actual expected "Should have a sequence of valid tweets" testCase "sequenceResultM with few invalid data" <| fun _ -> let tweets = - [ + seq { "" "Hello" aLongerInvalidTweet - ] - :> seq<_> + } let actual = Seq.sequenceResultM (Seq.map Tweet.TryCreate tweets) @@ -65,30 +135,599 @@ let sequenceResultMTests = (Error emptyTweetErrMsg) "traverse the sequence and return the first error" - testCase "sequenceResultM stops after first invalid data" + testCase "sequenceResultM with few invalid data should exit early" <| fun _ -> - let mutable counter = 0 + + let mutable lastValue = null + let mutable callCount = 0 let tweets = seq { - "Hi" + "" "Hello" - "Hola" aLongerInvalidTweet - - counter <- - counter - + 1 } - let actual = Seq.sequenceResultM (Seq.map Tweet.TryCreate tweets) + let tryCreate tweet = + callCount <- + callCount + + 1 + + match tweet with + | x when String.IsNullOrEmpty x -> Error "Tweet shouldn't be empty" + | x when x.Length > 280 -> Error "Tweet shouldn't contain more than 280 characters" + | x -> Ok(x) + + let actual = Seq.sequenceResultM (Seq.map tryCreate tweets) + + Expect.equal callCount 1 "Should have called the function only 1 time" + Expect.equal lastValue null "" Expect.equal actual - (Error longerTweetErrMsg) + (Error emptyTweetErrMsg) "traverse the sequence and return the first error" + ] + +let sequenceOptionMTests = + testList "Seq.sequenceOptionM Tests" [ + let tryTweetOption x = + match x with + | x when String.IsNullOrEmpty x -> None + | _ -> Some x + + testCase "traverseOption with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = Seq.toList tweets + let actual = Seq.sequenceOptionM (Seq.map tryTweetOption tweets) + + let actual = + Expect.wantSome actual "Expected result to be Some" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid tweets" + + testCase "sequenceOptionM with few invalid data" + <| fun _ -> + let tweets = + seq { + String.Empty + "Hello" + String.Empty + } + + let actual = Seq.sequenceOptionM (Seq.map tryTweetOption tweets) + + Expect.equal actual None "traverse the sequence and return none" + + testCase "sequenceOptionM with few invalid data should exit early" + <| fun _ -> + + let mutable lastValue = null + let mutable callCount = 0 + + let tweets = + seq { + "" + "Hello" + aLongerInvalidTweet + } + + let tryCreate tweet = + callCount <- + callCount + + 1 + + match tweet with + | x when String.IsNullOrEmpty x -> None + | x -> Some x + + let actual = Seq.sequenceOptionM (Seq.map tryCreate tweets) + + Expect.equal callCount 1 "Should have called the function only 1 time" + Expect.equal lastValue null "" + + Expect.equal actual None "traverse the sequence and return none" + ] + +let traverseResultATests = + testList "Seq.traverseResultA Tests" [ + testCase "traverseResultA with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = + Seq.map tweet tweets + |> Seq.toList + + let actual = Seq.traverseResultA Tweet.TryCreate tweets + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid tweets" + + testCase "traverseResultA with few invalid data" + <| fun _ -> + let tweets = + seq { + "" + "Hello" + aLongerInvalidTweet + } + + let actual = Seq.traverseResultA Tweet.TryCreate tweets + + let actual = + Expect.wantError actual "Expected result to be Error" + |> Seq.toList + + let expected = [ + emptyTweetErrMsg + longerTweetErrMsg + ] + + Expect.equal actual expected "traverse the sequence and return all the errors" + ] + +let sequenceResultATests = + testList "Seq.sequenceResultA Tests" [ + testCase "traverseResult with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = + Seq.map tweet tweets + |> Seq.toList + + let actual = Seq.sequenceResultA (Seq.map Tweet.TryCreate tweets) + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid tweets" + + testCase "sequenceResultM with few invalid data" + <| fun _ -> + let tweets = + seq { + "" + "Hello" + aLongerInvalidTweet + } + + let actual = Seq.sequenceResultA (Seq.map Tweet.TryCreate tweets) + + let actual = + Expect.wantError actual "Expected result to be Error" + |> Seq.toList + + let expected = [ + emptyTweetErrMsg + longerTweetErrMsg + ] + + Expect.equal actual expected "traverse the sequence and return all the errors" + ] + +let userId1 = Guid.NewGuid() +let userId2 = Guid.NewGuid() +let userId3 = Guid.NewGuid() +let userId4 = Guid.NewGuid() + +let traverseAsyncResultMTests = + + let userIds = + seq { + userId1 + userId2 + userId3 + } + |> Seq.map UserId + + testList "Seq.traverseAsyncResultM Tests" [ + testCaseAsync "traverseAsyncResultM with a sequence of valid data" + <| async { + let expected = + userIds + |> Seq.map (fun (UserId user) -> (newPostId, user)) + |> Seq.toList + + let! actual = Seq.traverseAsyncResultM (notifyNewPostSuccess (PostId newPostId)) userIds + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid data" + } + + testCaseAsync "traverseResultA with few invalid data" + <| async { + let expected = sprintf "error: %s" (userId1.ToString()) + + let actual = + Seq.traverseAsyncResultM (notifyNewPostFailure (PostId newPostId)) userIds + + do! Expect.hasAsyncErrorValue expected actual + } + ] + +let traverseAsyncOptionMTests = + + let userIds = + seq { + userId1 + userId2 + userId3 + } + + testList "Seq.traverseAsyncOptionM Tests" [ + testCaseAsync "traverseAsyncOptionM with a sequence of valid data" + <| async { + let expected = + userIds + |> Seq.toList + |> Some + + let f x = async { return Some x } + + let actual = + Seq.traverseAsyncOptionM f userIds + |> AsyncOption.map Seq.toList + + match expected with + | Some e -> do! Expect.hasAsyncSomeValue e actual + | None -> failwith "Error in the test case code" + } + + testCaseAsync "traverseOptionA with few invalid data" + <| async { + let expected = None + let f _ = async { return None } + let actual = Seq.traverseAsyncOptionM f userIds + + match expected with + | Some _ -> failwith "Error in the test case code" + | None -> do! Expect.hasAsyncNoneValue actual + } + ] + +let notifyFailure (PostId _) (UserId uId) = + async { + if + (uId = userId1 + || uId = userId3) + then + return + sprintf "error: %s" (uId.ToString()) + |> Error + else + return Ok() + } + + +let traverseAsyncResultATests = + let userIds = + seq { + userId1 + userId2 + userId3 + userId4 + } + |> Seq.map UserId + + testList "Seq.traverseAsyncResultA Tests" [ + testCaseAsync "traverseAsyncResultA with a sequence of valid data" + <| async { + let expected = + userIds + |> Seq.map (fun (UserId user) -> (newPostId, user)) + |> Seq.toList + + let! actual = Seq.traverseAsyncResultA (notifyNewPostSuccess (PostId newPostId)) userIds + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid data" + } - Expect.equal counter 0 "evaluation of the sequence stops at the first error" + testCaseAsync "traverseResultA with few invalid data" + <| async { + let expected = [ + sprintf "error: %s" (userId1.ToString()) + sprintf "error: %s" (userId3.ToString()) + ] + + let! actual = Seq.traverseAsyncResultA (notifyFailure (PostId newPostId)) userIds + + let actual = + Expect.wantError actual "Expected result to be Error" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of errors" + } ] -let allTests = testList "Seq Tests" [ sequenceResultMTests ] + +let sequenceAsyncResultMTests = + let userIds = + seq { + userId1 + userId2 + userId3 + userId4 + } + |> Seq.map UserId + + testList "Seq.sequenceAsyncResultM Tests" [ + testCaseAsync "sequenceAsyncResultM with a sequence of valid data" + <| async { + let expected = + userIds + |> Seq.map (fun (UserId user) -> (newPostId, user)) + |> Seq.toList + + let! actual = + Seq.map (notifyNewPostSuccess (PostId newPostId)) userIds + |> Seq.sequenceAsyncResultM + + let actual = + Expect.wantOk actual "Expected result to be Ok" + |> Seq.toList + + Expect.equal actual expected "Should have a sequence of valid data" + } + + testCaseAsync "sequenceAsyncResultM with few invalid data" + <| async { + let expected = sprintf "error: %s" (userId1.ToString()) + + let actual = + Seq.map (notifyFailure (PostId newPostId)) userIds + |> Seq.sequenceAsyncResultM + + do! Expect.hasAsyncErrorValue expected actual + } + ] + +let sequenceAsyncOptionMTests = + + let userIds = + seq { + userId1 + userId2 + userId3 + } + + testList "Seq.sequenceAsyncOptionM Tests" [ + testCaseAsync "sequenceAsyncOptionM with a sequence of valid data" + <| async { + let expected = + Seq.toList userIds + |> Some + + let f x = async { return Some x } + + let actual = + Seq.map f userIds + |> Seq.sequenceAsyncOptionM + |> AsyncOption.map Seq.toList + + match expected with + | Some e -> do! Expect.hasAsyncSomeValue e actual + | None -> failwith "Error in the test case code" + } + + testCaseAsync "sequenceOptionA with few invalid data" + <| async { + let expected = None + let f _ = async { return None } + + let actual = + Seq.map f userIds + |> Seq.sequenceAsyncOptionM + + match expected with + | Some _ -> failwith "Error in the test case code" + | None -> do! Expect.hasAsyncNoneValue actual + } + ] + +let sequenceAsyncResultATests = + let userIds = + seq { + userId1 + userId2 + userId3 + userId4 + } + |> Seq.map UserId + + testList "Seq.sequenceAsyncResultA Tests" [ + testCaseAsync "sequenceAsyncResultA with a sequence of valid data" + <| async { + let expected = + userIds + |> Seq.map (fun (UserId user) -> (newPostId, user)) + |> Seq.toList + + let actual = + Seq.map (notifyNewPostSuccess (PostId newPostId)) userIds + |> Seq.sequenceAsyncResultA + |> AsyncResult.map Seq.toList + + do! Expect.hasAsyncOkValue expected actual + } + + testCaseAsync "sequenceAsyncResultA with few invalid data" + <| async { + let expected = [ + sprintf "error: %s" (userId1.ToString()) + sprintf "error: %s" (userId3.ToString()) + ] + + let! actual = + Seq.map (notifyFailure (PostId newPostId)) userIds + |> Seq.sequenceAsyncResultA + |> AsyncResult.mapError Seq.toList + + let actual = Expect.wantError actual "Expected result to be Error" + Expect.equal actual expected "Should have a sequence of errors" + } + ] + +#if !FABLE_COMPILER +let traverseVOptionMTests = + testList "Seq.traverseVOptionM Tests" [ + let tryTweetVOption x = + match x with + | x when String.IsNullOrEmpty x -> ValueNone + | _ -> ValueSome x + + testCase "traverseVOption with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = Seq.toList tweets + + let actual = + Seq.traverseVOptionM tryTweetVOption tweets + |> ValueOption.map Seq.toList + + match actual with + | ValueSome actual -> + Expect.equal actual expected "Should have a sequence of valid tweets" + | ValueNone -> failwith "Expected a value some" + + testCase "traverseVOption with few invalid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + String.Empty + } + + let actual = Seq.traverseVOptionM tryTweetVOption tweets + Expect.equal actual ValueNone "traverse the sequence and return value none" + ] + +let sequenceVOptionMTests = + testList "Seq.sequenceVOptionM Tests" [ + let tryTweetOption x = + match x with + | x when String.IsNullOrEmpty x -> ValueNone + | _ -> ValueSome x + + testCase "traverseVOption with a sequence of valid data" + <| fun _ -> + let tweets = + seq { + "Hi" + "Hello" + "Hola" + } + + let expected = Seq.toList tweets + + let actual = + Seq.sequenceVOptionM (Seq.map tryTweetOption tweets) + |> ValueOption.map Seq.toList + + match actual with + | ValueSome actual -> + Expect.equal actual expected "Should have a sequence of valid tweets" + | ValueNone -> failwith "Expected a value some" + + testCase "sequenceVOptionM with few invalid data" + <| fun _ -> + let tweets = + seq { + String.Empty + "Hello" + String.Empty + } + + let actual = Seq.sequenceVOptionM (Seq.map tryTweetOption tweets) + Expect.equal actual ValueNone "traverse the sequence and return value none" + + testCase "sequenceVOptionM with few invalid data should exit early" + <| fun _ -> + + let mutable lastValue = null + let mutable callCount = 0 + + let tweets = + seq { + "" + "Hello" + aLongerInvalidTweet + } + + let tryCreate tweet = + callCount <- + callCount + + 1 + + match tweet with + | x when String.IsNullOrEmpty x -> ValueNone + | x -> ValueSome x + + let actual = Seq.sequenceVOptionM (Seq.map tryCreate tweets) + + match actual with + | ValueNone -> () + | ValueSome _ -> failwith "Expected a value none" + + Expect.equal callCount 1 "Should have called the function only 1 time" + Expect.equal lastValue null "" + ] + +#endif + +let allTests = + testList "List Tests" [ + traverseResultMTests + traverseOptionMTests + sequenceResultMTests + sequenceOptionMTests + traverseResultATests + sequenceResultATests + traverseAsyncResultMTests + traverseAsyncOptionMTests + traverseAsyncResultATests + sequenceAsyncResultMTests + sequenceAsyncOptionMTests + sequenceAsyncResultATests +#if !FABLE_COMPILER + traverseVOptionMTests + sequenceVOptionMTests +#endif + ]