| File: Extensions\IncrementalValuesProviderExtensions.cs | Web Access |
| Project: src\aspnetcore\src\Validation\gen\Microsoft.Extensions.Validation.ValidationsGenerator.csproj (Microsoft.Extensions.Validation.ValidationsGenerator) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; namespace Microsoft.Extensions.Validation; internal static class IncrementalValuesProviderExtensions { public static IncrementalValuesProvider<TSource> Distinct<TSource>(this IncrementalValuesProvider<TSource> source, IEqualityComparer<TSource> comparer) { return source .Collect() .WithComparer(ImmutableArrayEqualityComparer<TSource>.Instance) .SelectMany((values, cancellationToken) => { if (values.IsEmpty) { return values; } var results = ImmutableArray.CreateBuilder<TSource>(values.Length); HashSet<TSource> set = new(comparer); foreach (var value in values) { if (set.Add(value)) { results.Add(value); } } return results.DrainToImmutable(); }); } public static IncrementalValuesProvider<T> Concat<T>( this IncrementalValuesProvider<ImmutableArray<T>> first, IncrementalValuesProvider<ImmutableArray<T>> second) { return first.Collect() .Combine(second.Collect()) .SelectMany((tuple, _) => { if (tuple.Left.IsEmpty && tuple.Right.IsEmpty) { return []; } var results = ImmutableArray.CreateBuilder<T>(tuple.Left.Length + tuple.Right.Length); for (var i = 0; i < tuple.Left.Length; i++) { results.AddRange(tuple.Left[i]); } for (var i = 0; i < tuple.Right.Length; i++) { results.AddRange(tuple.Right[i]); } return results.DrainToImmutable(); }); } public static IncrementalValuesProvider<T> Concat<T>( this IncrementalValuesProvider<ImmutableArray<T>> first, IncrementalValuesProvider<T> second) { return first.Collect() .Combine(second.Collect()) .SelectMany((tuple, _) => { if (tuple.Left.IsEmpty) { return tuple.Right; } var results = ImmutableArray.CreateBuilder<T>(tuple.Left.Length + tuple.Right.Length); for (var i = 0; i < tuple.Left.Length; i++) { results.AddRange(tuple.Left[i]); } for (var i = 0; i < tuple.Right.Length; i++) { results.AddRange(tuple.Right[i]); } return results.DrainToImmutable(); }); } private sealed class ImmutableArrayEqualityComparer<T> : IEqualityComparer<ImmutableArray<T>> { public static readonly ImmutableArrayEqualityComparer<T> Instance = new(); public bool Equals(ImmutableArray<T> x, ImmutableArray<T> y) { if (x.IsDefault) { return y.IsDefault; } else if (y.IsDefault) { return false; } if (x.Length != y.Length) { return false; } for (var i = 0; i < x.Length; i++) { if (!EqualityComparer<T>.Default.Equals(x[i], y[i])) { return false; } } return true; } public int GetHashCode(ImmutableArray<T> obj) { if (obj.IsDefault) { return 0; } var hashCode = -450793227; foreach (var item in obj) { hashCode = (hashCode * -1521134295) + EqualityComparer<T>.Default.GetHashCode(item); } return hashCode; } } }