From 0bde6ed45f9a71b8dcc364c74182ffd4777993d3 Mon Sep 17 00:00:00 2001 From: JustArchi Date: Thu, 25 Jun 2020 17:07:58 +0200 Subject: [PATCH] Implement EnumSchemaFilter for swagger --- ...agsSchemaFilter.cs => EnumSchemaFilter.cs} | 54 +++++++++++++++++-- ArchiSteamFarm/IPC/Startup.cs | 6 +-- 2 files changed, 52 insertions(+), 8 deletions(-) rename ArchiSteamFarm/IPC/Integration/{EnumFlagsSchemaFilter.cs => EnumSchemaFilter.cs} (52%) diff --git a/ArchiSteamFarm/IPC/Integration/EnumFlagsSchemaFilter.cs b/ArchiSteamFarm/IPC/Integration/EnumSchemaFilter.cs similarity index 52% rename from ArchiSteamFarm/IPC/Integration/EnumFlagsSchemaFilter.cs rename to ArchiSteamFarm/IPC/Integration/EnumSchemaFilter.cs index 60d86ba97..c6b82bbe2 100644 --- a/ArchiSteamFarm/IPC/Integration/EnumFlagsSchemaFilter.cs +++ b/ArchiSteamFarm/IPC/Integration/EnumSchemaFilter.cs @@ -21,22 +21,70 @@ using System; using JetBrains.Annotations; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; namespace ArchiSteamFarm.IPC.Integration { [UsedImplicitly] - internal sealed class EnumFlagsSchemaFilter : ISchemaFilter { + internal sealed class EnumSchemaFilter : ISchemaFilter { public void Apply([NotNull] OpenApiSchema schema, [NotNull] SchemaFilterContext context) { if ((schema == null) || (context == null)) { throw new ArgumentNullException(nameof(schema) + " || " + nameof(context)); } - if (!context.Type.IsEnum || !context.Type.IsDefined(typeof(FlagsAttribute), false)) { + if (!context.Type.IsEnum) { return; } - schema.Format = "flags"; + if (context.Type.IsDefined(typeof(FlagsAttribute), false)) { + schema.Format = "flags"; + } + + OpenApiArray definition = new OpenApiArray(); + + foreach (object enumValue in context.Type.GetEnumValues()) { + string enumName = Enum.GetName(context.Type, enumValue); + + if (string.IsNullOrEmpty(enumName)) { + enumName = enumValue.ToString(); + + if (string.IsNullOrEmpty(enumName)) { + continue; + } + } + + IOpenApiAny enumObject; + + if (TryCast(enumValue, out int intValue)) { + enumObject = new OpenApiInteger(intValue); + } else if (TryCast(enumValue, out long longValue)) { + enumObject = new OpenApiLong(longValue); + } else if (TryCast(enumValue, out float floatValue)) { + enumObject = new OpenApiFloat(floatValue); + } else { + enumObject = new OpenApiString(enumValue.ToString()); + } + + OpenApiObject enumDefinition = new OpenApiObject { { enumName, enumObject } }; + + definition.Add(enumDefinition); + } + + schema.AddExtension("x-definition", definition); + } + + private static bool TryCast(object value, out T typedValue) { + try { + typedValue = (T) Convert.ChangeType(value, typeof(T)); + + return true; + } catch (InvalidCastException) { + typedValue = default; + + return false; + } } } } diff --git a/ArchiSteamFarm/IPC/Startup.cs b/ArchiSteamFarm/IPC/Startup.cs index 71b4ca89b..5d3cb28ab 100644 --- a/ArchiSteamFarm/IPC/Startup.cs +++ b/ArchiSteamFarm/IPC/Startup.cs @@ -35,7 +35,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; namespace ArchiSteamFarm.IPC { @@ -168,7 +167,7 @@ namespace ArchiSteamFarm.IPC { ); options.EnableAnnotations(true); - options.SchemaFilter(); + options.SchemaFilter(); options.SwaggerDoc( SharedInfo.ASF, new OpenApiInfo { @@ -236,9 +235,6 @@ namespace ArchiSteamFarm.IPC { // Fix default contract resolver to use original names and not a camel case options.SerializerSettings.ContractResolver = new DefaultContractResolver(); - // Use friendly names for enums instead of numbers - options.SerializerSettings.Converters.Add(new StringEnumConverter()); - if (Debugging.IsUserDebugging) { options.SerializerSettings.Formatting = Formatting.Indented; }