// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Analyzers { internal readonly struct DeclaredApiResponseMetadata { public static DeclaredApiResponseMetadata ImplicitResponse { get; } = new DeclaredApiResponseMetadata(statusCode: 0, attributeData: null, attributeSource: null, @implicit: true, @default: false); public static DeclaredApiResponseMetadata ForProducesResponseType(int statusCode, AttributeData attributeData, IMethodSymbol attributeSource) { return new DeclaredApiResponseMetadata(statusCode, attributeData, attributeSource, @implicit: false, @default: false); } public static DeclaredApiResponseMetadata ForProducesDefaultResponse(AttributeData attributeData, IMethodSymbol attributeSource) { return new DeclaredApiResponseMetadata(statusCode: 0, attributeData, attributeSource, @implicit: false, @default: true); } private DeclaredApiResponseMetadata( int statusCode, AttributeData attributeData, IMethodSymbol attributeSource, bool @implicit, bool @default) { StatusCode = statusCode; Attribute = attributeData; AttributeSource = attributeSource; IsImplicit = @implicit; IsDefault = @default; } public int StatusCode { get; } public AttributeData Attribute { get; } public IMethodSymbol AttributeSource { get; } public bool IsImplicit { get; } public bool IsDefault { get; } internal static bool Contains(IList declaredApiResponseMetadata, ActualApiResponseMetadata actualMetadata) { return TryGetDeclaredMetadata(declaredApiResponseMetadata, actualMetadata, out _); } internal static bool TryGetDeclaredMetadata( IList declaredApiResponseMetadata, ActualApiResponseMetadata actualMetadata, out DeclaredApiResponseMetadata result) { for (var i = 0; i < declaredApiResponseMetadata.Count; i++) { var declaredMetadata = declaredApiResponseMetadata[i]; if (declaredMetadata.Matches(actualMetadata)) { result = declaredMetadata; return true; } } result = default; return false; } internal bool Matches(ActualApiResponseMetadata actualMetadata) { if (actualMetadata.IsDefaultResponse) { return IsImplicit || StatusCode == 200 || StatusCode == 201; } else if (actualMetadata.StatusCode == StatusCode) { return true; } else if (actualMetadata.StatusCode >= 400 && IsDefault) { // ProducesDefaultResponse matches any failure code return true; } return false; } } }