|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | + |
| 4 | +using System.Linq; |
| 5 | +using Microsoft.OpenApi.Any; |
| 6 | + |
| 7 | +namespace Microsoft.AspNetCore.OpenApi; |
| 8 | + |
| 9 | +internal sealed class OpenApiAnyComparer : IEqualityComparer<IOpenApiAny> |
| 10 | +{ |
| 11 | + public static OpenApiAnyComparer Instance { get; } = new OpenApiAnyComparer(); |
| 12 | + |
| 13 | + public bool Equals(IOpenApiAny? x, IOpenApiAny? y) |
| 14 | + { |
| 15 | + if (x is null && y is null) |
| 16 | + { |
| 17 | + return true; |
| 18 | + } |
| 19 | + if (x is null || y is null) |
| 20 | + { |
| 21 | + return false; |
| 22 | + } |
| 23 | + if (object.ReferenceEquals(x, y)) |
| 24 | + { |
| 25 | + return true; |
| 26 | + } |
| 27 | + |
| 28 | + return x.AnyType == y.AnyType && |
| 29 | + (x switch |
| 30 | + { |
| 31 | + OpenApiNull _ => y is OpenApiNull, |
| 32 | + OpenApiArray arrayX => y is OpenApiArray arrayY && arrayX.SequenceEqual(arrayY, Instance), |
| 33 | + OpenApiObject objectX => y is OpenApiObject objectY && objectX.Keys.Count == objectY.Keys.Count && objectX.Keys.All(key => objectY.ContainsKey(key) && Equals(objectX[key], objectY[key])), |
| 34 | + OpenApiBinary binaryX => y is OpenApiBinary binaryY && binaryX.Value.SequenceEqual(binaryY.Value), |
| 35 | + OpenApiInteger integerX => y is OpenApiInteger integerY && integerX.Value == integerY.Value, |
| 36 | + OpenApiLong longX => y is OpenApiLong longY && longX.Value == longY.Value, |
| 37 | + OpenApiDouble doubleX => y is OpenApiDouble doubleY && doubleX.Value == doubleY.Value, |
| 38 | + OpenApiFloat floatX => y is OpenApiFloat floatY && floatX.Value == floatY.Value, |
| 39 | + OpenApiBoolean booleanX => y is OpenApiBoolean booleanY && booleanX.Value == booleanY.Value, |
| 40 | + OpenApiString stringX => y is OpenApiString stringY && stringX.Value == stringY.Value, |
| 41 | + OpenApiPassword passwordX => y is OpenApiPassword passwordY && passwordX.Value == passwordY.Value, |
| 42 | + OpenApiByte byteX => y is OpenApiByte byteY && byteX.Value.SequenceEqual(byteY.Value), |
| 43 | + OpenApiDate dateX => y is OpenApiDate dateY && dateX.Value == dateY.Value, |
| 44 | + OpenApiDateTime dateTimeX => y is OpenApiDateTime dateTimeY && dateTimeX.Value == dateTimeY.Value, |
| 45 | + _ => x.Equals(y) |
| 46 | + }); |
| 47 | + } |
| 48 | + |
| 49 | + public int GetHashCode(IOpenApiAny obj) |
| 50 | + { |
| 51 | + var hashCode = new HashCode(); |
| 52 | + hashCode.Add(obj.AnyType); |
| 53 | + if (obj is IOpenApiPrimitive primitive) |
| 54 | + { |
| 55 | + hashCode.Add(primitive.PrimitiveType); |
| 56 | + } |
| 57 | + if (obj is OpenApiBinary binary) |
| 58 | + { |
| 59 | + hashCode.AddBytes(binary.Value); |
| 60 | + } |
| 61 | + if (obj is OpenApiByte bytes) |
| 62 | + { |
| 63 | + hashCode.AddBytes(bytes.Value); |
| 64 | + } |
| 65 | + hashCode.Add<object?>(obj switch |
| 66 | + { |
| 67 | + OpenApiInteger integer => integer.Value, |
| 68 | + OpenApiLong @long => @long.Value, |
| 69 | + OpenApiDouble @double => @double.Value, |
| 70 | + OpenApiFloat @float => @float.Value, |
| 71 | + OpenApiBoolean boolean => boolean.Value, |
| 72 | + OpenApiString @string => @string.Value, |
| 73 | + OpenApiPassword password => password.Value, |
| 74 | + OpenApiDate date => date.Value, |
| 75 | + OpenApiDateTime dateTime => dateTime.Value, |
| 76 | + _ => null |
| 77 | + }); |
| 78 | + |
| 79 | + return hashCode.ToHashCode(); |
| 80 | + } |
| 81 | +} |
0 commit comments