From 919c4a0aeb0cc99fe72a1a4d64b3587efcf1aa47 Mon Sep 17 00:00:00 2001 From: Joel Mueller Date: Tue, 21 May 2024 22:25:36 -0500 Subject: [PATCH] CopyValuesTo and CopyErrorsTo for Result --- .../Async/ResultAsyncExtensions.cs | 4 + src/RustyOptions/NumericOptionExtensions.cs | 15 +- .../OptionCollectionExtensions.cs | 20 ++- .../ResultCollectionExtensions.cs | 166 +++++++++++++++++- 4 files changed, 185 insertions(+), 20 deletions(-) diff --git a/src/RustyOptions/Async/ResultAsyncExtensions.cs b/src/RustyOptions/Async/ResultAsyncExtensions.cs index ca79276..46655f9 100644 --- a/src/RustyOptions/Async/ResultAsyncExtensions.cs +++ b/src/RustyOptions/Async/ResultAsyncExtensions.cs @@ -731,6 +731,10 @@ public static async ValueTask> OrElseAsync(thi return Result.Ok(result.Unwrap()); } + // NOTE: Due to a bug in coverlet.collector, certain lines in methods involving IAsyncEnumerable + // will show as partially-covered in code-coverage tools, even when they are fully-covered. + // https://github.com/coverlet-coverage/coverlet/issues/1104#issuecomment-1005332269 + /// /// Flattens an asynchronous sequence of into a sequence containing all inner values. /// Error results are discarded. diff --git a/src/RustyOptions/NumericOptionExtensions.cs b/src/RustyOptions/NumericOptionExtensions.cs index df53773..5790ed1 100644 --- a/src/RustyOptions/NumericOptionExtensions.cs +++ b/src/RustyOptions/NumericOptionExtensions.cs @@ -267,8 +267,9 @@ public static IEnumerable Values(this IEnumerable> self) } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in an array + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. @@ -285,8 +286,9 @@ public static Span CopyValuesTo(this NumericOption[] self, Span dest } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in a list + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. @@ -303,8 +305,9 @@ public static Span CopyValuesTo(this List> self, Span } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. diff --git a/src/RustyOptions/OptionCollectionExtensions.cs b/src/RustyOptions/OptionCollectionExtensions.cs index 5c019fb..ea97f36 100644 --- a/src/RustyOptions/OptionCollectionExtensions.cs +++ b/src/RustyOptions/OptionCollectionExtensions.cs @@ -40,8 +40,9 @@ public static IEnumerable Values(this IEnumerable> self) } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in an array + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. @@ -58,8 +59,9 @@ public static Span CopyValuesTo(this Option[] self, Span destination } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in a List + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. @@ -76,8 +78,9 @@ public static Span CopyValuesTo(this List> self, Span destina } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. @@ -94,8 +97,9 @@ public static Span CopyValuesTo(this Span> self, Span destina } /// - /// Copies the inner values of all in a span to a span, - /// returning the destination span trimmed to the number of values copied. + /// Copies the inner values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. /// /// The type of the numeric option values. /// The source span of numeric options. diff --git a/src/RustyOptions/ResultCollectionExtensions.cs b/src/RustyOptions/ResultCollectionExtensions.cs index 91650fc..2f2d4d9 100644 --- a/src/RustyOptions/ResultCollectionExtensions.cs +++ b/src/RustyOptions/ResultCollectionExtensions.cs @@ -1,4 +1,6 @@ -using static System.ArgumentNullException; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using static System.ArgumentNullException; namespace RustyOptions; @@ -7,10 +9,6 @@ namespace RustyOptions; /// public static class ResultCollectionExtensions { - // NOTE: Due to a bug in coverlet.collector, certain lines in methods involving IAsyncEnumerable - // will show as partially-covered in code-coverage tools, even when they are fully-covered. - // https://github.com/coverlet-coverage/coverlet/issues/1104#issuecomment-1005332269 - /// /// Flattens a sequence of into a sequence containing all inner values. /// Error results are discarded. @@ -32,7 +30,84 @@ public static IEnumerable Values(this IEnumerable> s } } - // TODO: Span overload for Values? + /// + /// Copies the inner values of all in an array + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the values to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the values. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyValuesTo(this Result[] self, Span destination) + where T : notnull + { + return CopyValuesTo((ReadOnlySpan>)self, destination); + } + + /// + /// Copies the inner values of all in a List + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the values to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the values. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyValuesTo(this List> self, Span destination) + where T : notnull + { + return CollectionsMarshal.AsSpan(self).CopyValuesTo(destination); + } + + /// + /// Copies the inner values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the values to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the values. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyValuesTo(this Span> self, Span destination) + where T : notnull + { + return CopyValuesTo((ReadOnlySpan>)self, destination); + } + + /// + /// Copies the inner values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the values to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the values. + /// + public static Span CopyValuesTo(this ReadOnlySpan> self, Span destination) + where T : notnull + { + int j = 0; + for (int i = 0; i < self.Length; i++) + { + if (self[i].IsOk(out var value)) + { + destination[j++] = value; + } + } + return destination[..j]; + } /// /// Flattens a sequence of into a sequence containing all error values. @@ -54,4 +129,83 @@ public static IEnumerable Errors(this IEnumerable } } } + + /// + /// Copies the error values of all in an array + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the errors to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the errors. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyErrorssTo(this Result[] self, Span destination) + where T : notnull + { + return CopyErrorsTo((ReadOnlySpan>)self, destination); + } + + /// + /// Copies the error values of all in a List + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the errors to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the errors. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyErrorsTo(this List> self, Span destination) + where T : notnull + { + return CollectionsMarshal.AsSpan(self).CopyErrorsTo(destination); + } + + /// + /// Copies the error values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the errors to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the errors. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span CopyErrorsTo(this Span> self, Span destination) + where T : notnull + { + return CopyErrorsTo((ReadOnlySpan>)self, destination); + } + + /// + /// Copies the error values of all in a span + /// to a span, returning the destination span + /// trimmed to the number of values copied. Error results are discarded. + /// + /// The source span of results. + /// The destination span to copy the errors to. + /// A flattened sequence of values. + /// + /// Thrown if the destination span is too small to hold all the errors. + /// + public static Span CopyErrorsTo(this ReadOnlySpan> self, Span destination) + where T : notnull + { + int j = 0; + for (int i = 0; i < self.Length; i++) + { + if (self[i].IsErr(out var err) && err is not null) + { + destination[j++] = err; + } + } + return destination[..j]; + } }