-
-
Notifications
You must be signed in to change notification settings - Fork 38
/
RefitInterfaceGenerator.cs
116 lines (94 loc) · 3.94 KB
/
RefitInterfaceGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.Text;
using NSwag;
namespace Refitter.Core;
public class RefitInterfaceGenerator
{
private const string Separator = " ";
private readonly RefitGeneratorSettings settings;
private readonly OpenApiDocument document;
private readonly CustomCSharpClientGenerator generator;
public RefitInterfaceGenerator(
RefitGeneratorSettings settings,
OpenApiDocument document,
CustomCSharpClientGenerator generator)
{
this.settings = settings;
this.document = document;
this.generator = generator;
}
public string GenerateRefitInterface()
{
var code = new StringBuilder();
code.AppendLine(GenerateInterfaceDeclaration());
code.AppendLine(GenerateInterfaceBody());
return code.ToString();
}
private string GenerateInterfaceBody()
{
var code = new StringBuilder();
foreach (var kv in document.Paths)
{
foreach (var operations in kv.Value)
{
var operation = operations.Value;
var returnTypeParameter = operation.Responses.ContainsKey("200")
? generator.GetTypeName(operation.Responses["200"].ActualResponse.Schema, true, null)
: null;
var returnType = GetReturnType(returnTypeParameter);
var verb = operations.Key.CapitalizeFirstCharacter();
var name = generator.BaseSettings.OperationNameGenerator
.GetOperationName(document, kv.Key, verb, operation)
.CapitalizeFirstCharacter()
.ConvertKebabCaseToPascalCase();
var parameters = ParameterExtractor.GetParameters(generator, operation, settings);
var parametersString = string.Join(", ", parameters);
GenerateMethodXmlDocComments(operation, code);
code.AppendLine($"{Separator}{Separator}[{verb}(\"{kv.Key}\")]")
.AppendLine($"{Separator}{Separator}{returnType} {name}({parametersString});")
.AppendLine();
}
}
code.AppendLine($"{Separator}}}");
return code.ToString();
}
private string GetReturnType(string? returnTypeParameter)
{
return returnTypeParameter is null or "void"
? "Task"
: GetConfiguredReturnType(returnTypeParameter);
}
private string GetConfiguredReturnType(string returnTypeParameter)
{
return settings.ReturnIApiResponse
? $"Task<IApiResponse<{WellKnownNamesspaces.TrimImportedNamespaces(returnTypeParameter)}>>"
: $"Task<{WellKnownNamesspaces.TrimImportedNamespaces(returnTypeParameter)}>";
}
private void GenerateMethodXmlDocComments(OpenApiOperation operation, StringBuilder code)
{
if (!settings.GenerateXmlDocCodeComments)
return;
if (!string.IsNullOrWhiteSpace(operation.Description))
{
code.AppendLine($"{Separator}{Separator}/// <summary>");
foreach (var line in operation.Description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None))
code.AppendLine($"{Separator}{Separator}/// {line.Trim()}");
code.AppendLine($"{Separator}{Separator}/// </summary>");
}
}
private string GenerateInterfaceDeclaration()
{
var title = settings.Naming.UseOpenApiTitle
? document.Info?.Title?
.Replace(" ", string.Empty)
.Replace("-", string.Empty)
.Replace(".", string.Empty) ??
"ApiClient"
: settings.Naming.InterfaceName;
var code = new StringBuilder();
var modifier = settings.TypeAccessibility.ToString().ToLowerInvariant();
code.AppendLine($"{Separator}{modifier} interface I{title.CapitalizeFirstCharacter()}")
.AppendLine($"{Separator}{{");
return code.ToString();
}
}