@@ -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+ }
0 commit comments