Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't generate enum item descriptions #1685

Closed
Mazas17 opened this issue May 29, 2020 · 3 comments · Fixed by #2943
Closed

Can't generate enum item descriptions #1685

Mazas17 opened this issue May 29, 2020 · 3 comments · Fixed by #2943
Labels
help-wanted A change up for grabs for contributions from the community p2 Medium priority

Comments

@Mazas17
Copy link

Mazas17 commented May 29, 2020

According to OpenAPI documentation, it is possible to add description to single enum item:

      parameters:
        - in: query
          name: sort
          schema:
            type: string
            enum: [asc, desc]
          description: >
            Sort order:
             * `asc` - Ascending, from A to Z
             * `desc` - Descending, from Z to A

https://swagger.io/docs/specification/data-models/enums/

How to do that with swashbuckle? Can't find any documentation

@domaindrivendev domaindrivendev added the p2 Medium priority label Jan 18, 2021
@cadmaticpgustafsson
Copy link

This would be a nice feature. I found this article which describes how you can do it manually, not sure if this works with the latest version. I have not tried.

@martincostello martincostello added the help-wanted A change up for grabs for contributions from the community label May 6, 2024
@jgarciadelanoceda
Copy link
Contributor

jgarciadelanoceda commented Jun 4, 2024

Right now if you combine that with a DocumentFilter you will have everything.

public class EnumDocumentFilter : IDocumentFilter
{
	public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
	{
		foreach (var path in swaggerDoc.Paths.Values)
		{
			foreach (var operation in path.Operations.Values)
			{
				foreach (var parameter in operation.Parameters)
				{
					var schematypeId = parameter.Schema.Reference?.Id;

					if (!string.IsNullOrEmpty(schematypeId) && context.SchemaRepository.Schemas.TryGetValue(schematypeId, out var schema))
					{
						if ((schema.Enum?.Count ?? 0) > 0)
						{
							parameter.Description = schema.Description;
						}
					}
					if (!string.IsNullOrWhiteSpace(parameter.Schema.Description))
					{
						parameter.Description = parameter.Schema.Description;
					}
				}
			}
		}
	}
}

The SchemaFilter:

public class EnumSchemaFilter : ISchemaFilter
{
	public void Apply(OpenApiSchema schema, SchemaFilterContext context)
	{
		bool isEnumArgument = (context.Type?.GenericTypeArguments?.Length ?? 0) == 1 && context.Type.GenericTypeArguments.All(b => b.IsEnum);
		var isEnumArray = context.Type.IsArray && context.Type.GetElementType().IsEnum;
		if (context.Type.IsEnum || isEnumArgument || isEnumArray)
		{
			Type enumType = (context.Type.IsEnum, isEnumArgument, isEnumArray) switch
			{
				(true, _, _) => context.Type,
				(_, true, _) => context.Type.GenericTypeArguments.First(),
				_ => context.Type.GetElementType()
			};

			StringBuilder stringBuilder = new("<p>Members:</p><ul>");
			OpenApiArray names = [];
			foreach (var enumValue in Enum.GetValues(enumType))
			{
				if (enumValue is Enum value)
				{
					names.Add(new OpenApiString(value.ToString()));
					stringBuilder.Append($"<li>{value} - {value:d}</li>");
				}
			}
			schema.Extensions.Add("x-enum-varnames", names);
			schema.Description = stringBuilder.Append("</ul>").ToString();
		}
	}
}

I will investigate if it's interesting insert this into the library

@jgarciadelanoceda
Copy link
Contributor

jgarciadelanoceda commented Jun 11, 2024

The IDocumentFilter could be replaced by a IParameterFilter that it's much simpler:

public class ParameterFilter : IParameterFilter
{
	public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
	{
		if (string.IsNullOrWhiteSpace(parameter.Description))
		{
			parameter.Description = parameter.Schema.Description;
			if (string.IsNullOrEmpty(parameter.Description)
				&& !string.IsNullOrEmpty(parameter.Schema?.Reference?.Id)
				&& context.SchemaRepository.Schemas.TryGetValue(parameter.Schema.Reference.Id, out var value))
			{
				parameter.Description = value.Description;
			}
		}
	}
}

I am trying to see if I can add this copy of information from the Schema into the library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help-wanted A change up for grabs for contributions from the community p2 Medium priority
Projects
None yet
5 participants