Skip to content

Commit ac9de30

Browse files
committed
feat: improve ContentGeneratorServerConfigureSwaggerDocOptions for description
1 parent af1a85f commit ac9de30

File tree

3 files changed

+179
-90
lines changed

3 files changed

+179
-90
lines changed

src/Atc.Rest.ApiGenerator.Framework/ContentGenerators/Server/ContentGeneratorServerConfigureSwaggerDocOptions.cs

Lines changed: 177 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public string Generate()
2121
var sb = new StringBuilder();
2222

2323
sb.Append(codeHeaderGenerator.Generate());
24-
sb.AppendLine($"namespace {parameters.Namespace}.Options;"); // TODO: Move to constant
24+
sb.AppendLine($"namespace {parameters.Namespace}.Options;");
2525
sb.AppendLine();
2626
sb.AppendLine(codeAttributeGenerator.Generate());
2727
sb.AppendLine("public class ConfigureSwaggerDocOptions : IConfigureOptions<SwaggerGenOptions>");
@@ -58,114 +58,203 @@ public string Generate()
5858
sb.AppendLine(8, "ApiVersionDescription description)");
5959
sb.AppendLine(4, "{");
6060

61-
var description = string.Empty;
62-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.Description))
61+
var opts = parameters.SwaggerDocOptions;
62+
var descriptionText = string.Empty;
63+
if (!string.IsNullOrWhiteSpace(opts.Description))
6364
{
64-
description = parameters.SwaggerDocOptions.Description!
65+
descriptionText = opts.Description!
6566
.Replace("\"", string.Empty, StringComparison.Ordinal)
6667
.Replace("'", string.Empty, StringComparison.Ordinal)
6768
.Trim();
6869
}
6970

70-
sb.AppendLine(8, $"var text = new StringBuilder(@\"{description}\");");
71-
sb.AppendLine(8, "var info = new OpenApiInfo");
72-
sb.AppendLine(8, "{");
73-
sb.AppendLine(12, "Title = $\"{environment.ApplicationName} {description.GroupName.ToUpperInvariant()}\",");
74-
sb.AppendLine(12, "Version = description.ApiVersion.ToString(),");
75-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactName) ||
76-
!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactEmail) ||
77-
!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactUrl))
78-
{
79-
sb.AppendLine(12, "Contact = new OpenApiContact");
80-
sb.AppendLine(12, "{");
81-
82-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactName))
83-
{
84-
sb.AppendLine(16, $"Name = \"{parameters.SwaggerDocOptions.ContactName}\",");
85-
}
71+
AppendStringBuilderInit(sb, 8, descriptionText);
72+
AppendApiInfo(sb, 8, opts);
73+
AppendSunsetPolicyBlock(sb, 8);
8674

87-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactEmail))
88-
{
89-
sb.AppendLine(16, $"Email = \"{parameters.SwaggerDocOptions.ContactEmail}\",");
90-
}
91-
92-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.ContactUrl))
93-
{
94-
sb.AppendLine(16, $"Url = new Uri(\"{parameters.SwaggerDocOptions.ContactUrl}\"),");
95-
}
75+
sb.AppendLine(8, "info.Description = text.ToString();");
76+
sb.AppendLine();
77+
sb.AppendLine(8, "return info;");
78+
sb.AppendLine(4, "}");
79+
sb.Append('}');
9680

97-
sb.AppendLine(12, "},");
98-
}
81+
return sb.ToString();
82+
}
9983

100-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.TermsOfService))
101-
{
102-
sb.AppendLine(12, $"TermsOfService = new Uri(\"{parameters.SwaggerDocOptions.TermsOfService}\"),");
103-
}
84+
private static void AppendApiInfo(
85+
StringBuilder sb,
86+
int baseIndent,
87+
SwaggerDocOptionsParameters opts)
88+
{
89+
var indent = baseIndent + 4;
10490

105-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.LicenseName) ||
106-
!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.LicenseUrl))
107-
{
108-
sb.AppendLine(12, "License = new OpenApiLicense");
109-
sb.AppendLine(12, "{");
91+
sb.AppendLine(baseIndent, "var info = new OpenApiInfo");
92+
sb.AppendLine(baseIndent, "{");
93+
sb.AppendLine(indent, "Title = $\"{environment.ApplicationName} {description.GroupName.ToUpperInvariant()}\",");
94+
sb.AppendLine(indent, "Version = description.ApiVersion.ToString(),");
11095

111-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.LicenseName))
112-
{
113-
sb.AppendLine(16, $"Name = \"{parameters.SwaggerDocOptions.LicenseName}\",");
114-
}
96+
AppendContact(sb, indent, opts.ContactName, opts.ContactEmail, opts.ContactUrl);
97+
AppendTermsOfService(sb, indent, opts.TermsOfService);
98+
AppendLicense(sb, indent, opts.LicenseName, opts.LicenseUrl);
11599

116-
if (!string.IsNullOrWhiteSpace(parameters.SwaggerDocOptions.LicenseUrl))
117-
{
118-
sb.AppendLine(16, $"Url = new Uri(\"{parameters.SwaggerDocOptions.LicenseUrl}\"),");
119-
}
100+
sb.AppendLine(baseIndent, "};");
101+
sb.AppendLine();
102+
}
120103

121-
sb.AppendLine(12, "},");
122-
}
104+
private static void AppendSunsetPolicyBlock(
105+
StringBuilder sb,
106+
int baseIndent)
107+
{
108+
var i1 = baseIndent + 4;
109+
var i2 = i1 + 4;
110+
var i3 = i2 + 4;
111+
var i4 = i3 + 4;
123112

124-
sb.AppendLine(8, "};");
113+
sb.AppendLine(baseIndent, "if (description.IsDeprecated)");
114+
sb.AppendLine(baseIndent, "{");
115+
sb.AppendLine(i1, "text.Append(\" This API version has been deprecated.\");");
116+
sb.AppendLine(baseIndent, "}");
125117
sb.AppendLine();
126-
sb.AppendLine(8, "if (description.IsDeprecated)");
127-
sb.AppendLine(8, "{");
128-
sb.AppendLine(12, "text.Append(\" This API version has been deprecated.\");");
129-
sb.AppendLine(8, "}");
130-
sb.AppendLine();
131-
sb.AppendLine(8, "if (description.SunsetPolicy is { } policy)");
132-
sb.AppendLine(8, "{");
133-
sb.AppendLine(12, "if (policy.Date is { } when)");
134-
sb.AppendLine(12, "{");
135-
sb.AppendLine(16, "text.Append(\" The API will be sunset on \")");
136-
sb.AppendLine(20, ".Append(when.Date.ToShortDateString())");
137-
sb.AppendLine(20, ".Append('.');");
138-
sb.AppendLine(12, "}");
118+
sb.AppendLine(baseIndent, "if (description.SunsetPolicy is { } policy)");
119+
sb.AppendLine(baseIndent, "{");
120+
sb.AppendLine(i1, "if (policy.Date is { } when)");
121+
sb.AppendLine(i1, "{");
122+
sb.AppendLine(i2, "text.Append(\" The API will be sunset on \")");
123+
sb.AppendLine(i3, ".Append(when.Date.ToShortDateString())");
124+
sb.AppendLine(i3, ".Append('.');");
125+
sb.AppendLine(i1, "}");
139126
sb.AppendLine();
140-
sb.AppendLine(12, "if (policy.HasLinks)");
141-
sb.AppendLine(12, "{");
142-
sb.AppendLine(16, "text.AppendLine();");
127+
sb.AppendLine(i1, "if (policy.HasLinks)");
128+
sb.AppendLine(i1, "{");
129+
sb.AppendLine(i2, "text.AppendLine();");
143130
sb.AppendLine();
144-
sb.AppendLine(16, "foreach (var link in policy.Links)");
145-
sb.AppendLine(16, "{");
146-
sb.AppendLine(20, "if (link.Type != \"text/html\")");
147-
sb.AppendLine(20, "{");
148-
sb.AppendLine(24, "continue;");
149-
sb.AppendLine(20, "}");
131+
sb.AppendLine(i2, "foreach (var link in policy.Links)");
132+
sb.AppendLine(i2, "{");
133+
sb.AppendLine(i3, "if (link.Type != \"text/html\")");
134+
sb.AppendLine(i3, "{");
135+
sb.AppendLine(i4, "continue;");
136+
sb.AppendLine(i3, "}");
150137
sb.AppendLine();
151-
sb.AppendLine(20, "text.AppendLine();");
138+
sb.AppendLine(i3, "text.AppendLine();");
152139
sb.AppendLine();
153-
sb.AppendLine(20, "if (link.Title.HasValue)");
154-
sb.AppendLine(20, "{");
155-
sb.AppendLine(24, "text.Append(link.Title.Value).Append(\": \");");
156-
sb.AppendLine(20, "}");
140+
sb.AppendLine(i3, "if (link.Title.HasValue)");
141+
sb.AppendLine(i3, "{");
142+
sb.AppendLine(i4, "text.Append(link.Title.Value).Append(\": \");");
143+
sb.AppendLine(i3, "}");
157144
sb.AppendLine();
158-
sb.AppendLine(20, "text.Append(link.LinkTarget.OriginalString);");
159-
sb.AppendLine(16, "}");
160-
sb.AppendLine(12, "}");
161-
sb.AppendLine(8, "}");
145+
sb.AppendLine(i3, "text.Append(link.LinkTarget.OriginalString);");
146+
sb.AppendLine(i2, "}");
147+
sb.AppendLine(i1, "}");
148+
sb.AppendLine(baseIndent, "}");
162149
sb.AppendLine();
163-
sb.AppendLine(8, "info.Description = text.ToString();");
150+
}
151+
152+
private static void AppendStringBuilderInit(
153+
StringBuilder sb,
154+
int baseIndent,
155+
string? text)
156+
{
157+
sb.Append(baseIndent, "var text = new StringBuilder(");
158+
if (!string.IsNullOrEmpty(text))
159+
{
160+
sb.Append(BuildStringLiteral(text));
161+
}
162+
sb.Append(");");
164163
sb.AppendLine();
165-
sb.AppendLine(8, "return info;");
166-
sb.AppendLine(4, "}");
167-
sb.Append('}');
164+
}
168165

169-
return sb.ToString();
166+
private static void AppendContact(
167+
StringBuilder sb,
168+
int baseIndent,
169+
string? name,
170+
string? email,
171+
string? url)
172+
{
173+
if (!Has(name) &&
174+
!Has(email) &&
175+
!Has(url))
176+
{
177+
return;
178+
}
179+
180+
var innerIndent = baseIndent + 4;
181+
182+
sb.AppendLine(baseIndent, "Contact = new OpenApiContact");
183+
sb.AppendLine(baseIndent, "{");
184+
if (Has(name))
185+
{
186+
sb.AppendLine(innerIndent, $"Name = {BuildStringLiteral(name!)},");
187+
}
188+
189+
if (Has(email))
190+
{
191+
sb.AppendLine(innerIndent, $"Email = {BuildStringLiteral(email!)},");
192+
}
193+
194+
if (Has(url))
195+
{
196+
sb.AppendLine(innerIndent, $"Url = new Uri({BuildStringLiteral(url!)}),");
197+
}
198+
199+
sb.AppendLine(baseIndent, "},");
170200
}
171-
}
201+
202+
private static void AppendTermsOfService(
203+
StringBuilder sb,
204+
int indentBase,
205+
string? termsUrl)
206+
{
207+
if (Has(termsUrl))
208+
{
209+
sb.AppendLine(indentBase, $"TermsOfService = new Uri({BuildStringLiteral(termsUrl!)}),");
210+
}
211+
}
212+
213+
private static void AppendLicense(
214+
StringBuilder sb,
215+
int indentBase,
216+
string? licenseName,
217+
string? licenseUrl)
218+
{
219+
if (!Has(licenseName) &&
220+
!Has(licenseUrl))
221+
{
222+
return;
223+
}
224+
225+
var innerIndent = indentBase + 4;
226+
227+
sb.AppendLine(indentBase, "License = new OpenApiLicense");
228+
sb.AppendLine(indentBase, "{");
229+
if (Has(licenseName))
230+
{
231+
sb.AppendLine(innerIndent, $"Name = {BuildStringLiteral(licenseName!)},");
232+
}
233+
234+
if (Has(licenseUrl))
235+
{
236+
sb.AppendLine(innerIndent, $"Url = new Uri({BuildStringLiteral(licenseUrl!)}),");
237+
}
238+
239+
sb.AppendLine(indentBase, "},");
240+
}
241+
242+
private static string BuildStringLiteral(
243+
string text)
244+
{
245+
// Use verbatim if backslashes or newlines are present.
246+
if (text.IndexOfAny(new[] { '\\', '\r', '\n' }) >= 0)
247+
{
248+
var verbatim = text.Replace("\"", "\"\"");
249+
return "@\"" + verbatim + "\"";
250+
}
251+
252+
// Otherwise, use a normal C# string literal.
253+
var normal = text.Replace("\\", "\\\\").Replace("\"", "\\\"");
254+
return "\"" + normal + "\"";
255+
}
256+
257+
private static bool Has(
258+
string? s)
259+
=> !string.IsNullOrWhiteSpace(s);
260+
}

test/Atc.Rest.ApiGenerator.CLI.Tests/Scenarios/PetStore/VerifyServerAll/Mvc_WOPD/src/PetStore.Api/Options/ConfigureSwaggerDocOptions.verified.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void Configure(
3939
private OpenApiInfo CreateInfoForApiVersion(
4040
ApiVersionDescription description)
4141
{
42-
var text = new StringBuilder("");
42+
var text = new StringBuilder();
4343
var info = new OpenApiInfo
4444
{
4545
Title = $"{environment.ApplicationName} {description.GroupName.ToUpperInvariant()}",

test/Atc.Rest.ApiGenerator.CLI.Tests/Scenarios/PetStore/VerifyServerAll/Mvc_WPD/src/PetStore.Api/Options/ConfigureSwaggerDocOptions.verified.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void Configure(
3939
private OpenApiInfo CreateInfoForApiVersion(
4040
ApiVersionDescription description)
4141
{
42-
var text = new StringBuilder("");
42+
var text = new StringBuilder();
4343
var info = new OpenApiInfo
4444
{
4545
Title = $"{environment.ApplicationName} {description.GroupName.ToUpperInvariant()}",

0 commit comments

Comments
 (0)