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

make use of new language features #72

Merged
merged 1 commit into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/Refitter.Core/ParameterExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,11 @@ public static IEnumerable<string> GetParameters(

private static string GetQueryAttribute(CSharpParameterModel p)
{
if (p.IsArray)
return "Query(CollectionFormat.Multi)";
else
return p switch
{
return "Query";
}
{ IsArray: true } => "Query(CollectionFormat.Multi)",
_ => "Query",
};
}

private static string GetAliasAsAttribute(CSharpParameterModel parameterModel) =>
Expand Down
139 changes: 71 additions & 68 deletions src/Refitter.Core/RefitGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,87 +1,90 @@
using System.Linq;
using NSwag;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NSwag;

namespace Refitter.Core
namespace Refitter.Core;

public class RefitGenerator
{
public class RefitGenerator
private readonly RefitGeneratorSettings settings;
private readonly OpenApiDocument document;
private readonly CSharpClientGeneratorFactory factory;

private RefitGenerator(RefitGeneratorSettings settings, OpenApiDocument document)
{
private readonly RefitGeneratorSettings settings;
private readonly OpenApiDocument document;
private readonly CSharpClientGeneratorFactory factory;
this.settings = settings;
this.document = document;
factory = new CSharpClientGeneratorFactory(settings, document);
}

private RefitGenerator(RefitGeneratorSettings settings, OpenApiDocument document)
{
this.settings = settings;
this.document = document;
factory = new CSharpClientGeneratorFactory(settings, document);
}
public static async Task<RefitGenerator> CreateAsync(RefitGeneratorSettings settings)
{
if (IsHttp(settings.OpenApiPath) && IsYaml(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiYamlDocument.FromUrlAsync(settings.OpenApiPath));
if (IsHttp(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiDocument.FromUrlAsync(settings.OpenApiPath));
if (IsYaml(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiYamlDocument.FromFileAsync(settings.OpenApiPath));
return new RefitGenerator(settings, await OpenApiDocument.FromFileAsync(settings.OpenApiPath));
}

public static async Task<RefitGenerator> CreateAsync(RefitGeneratorSettings settings)
{
if (IsHttp(settings.OpenApiPath) && IsYaml(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiYamlDocument.FromUrlAsync(settings.OpenApiPath));
if (IsHttp(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiDocument.FromUrlAsync(settings.OpenApiPath));
if (IsYaml(settings.OpenApiPath))
return new RefitGenerator(settings, await OpenApiYamlDocument.FromFileAsync(settings.OpenApiPath));
return new RefitGenerator(settings, await OpenApiDocument.FromFileAsync(settings.OpenApiPath));
}
public string Generate()
{
var generator = factory.Create();
var contracts = RefitInterfaceImports
.GetImportedNamespaces(settings)
.Aggregate(
generator.GenerateFile(),
(current, import) => current.Replace($"{import}.", string.Empty));

public string Generate()
{
var generator = factory.Create();
var contracts = RefitInterfaceImports
.GetImportedNamespaces(settings)
.Aggregate(
generator.GenerateFile(),
(current, import) => current.Replace($"{import}.", string.Empty));
var interfaceGenerator = new RefitInterfaceGenerator(settings, document, generator);
var client = GenerateClient(interfaceGenerator);

var interfaceGenerator = new RefitInterfaceGenerator(settings, document, generator);
var client = GenerateClient(interfaceGenerator);
return new StringBuilder()
.AppendLine(client)
.AppendLine()
.AppendLine(settings.GenerateContracts ? contracts : string.Empty)
.ToString();
}

return new StringBuilder()
.AppendLine(client)
.AppendLine()
.AppendLine(settings.GenerateContracts ? contracts : string.Empty)
.ToString();
}
private string GenerateClient(RefitInterfaceGenerator interfaceGenerator)
{
var code = new StringBuilder();
GenerateAutoGeneratedHeader(code);
code.AppendLine(RefitInterfaceImports.GenerateNamespaceImports(settings))
.AppendLine();

private string GenerateClient(RefitInterfaceGenerator interfaceGenerator)
{
var code = new StringBuilder();
GenerateAutoGeneratedHeader(code);
code.AppendLine(RefitInterfaceImports.GenerateNamespaceImports(settings))
.AppendLine();
code.AppendLine($$"""
namespace {{settings.Namespace}}
{
{{interfaceGenerator.GenerateRefitInterface()}}
}
""");

code.AppendLine("namespace " + settings.Namespace)
.AppendLine("{")
.AppendLine(interfaceGenerator.GenerateRefitInterface())
.AppendLine("}");
return code.ToString();
}

return code.ToString();
}
private void GenerateAutoGeneratedHeader(StringBuilder code)
{
if (!settings.AddAutoGeneratedHeader)
return;

private void GenerateAutoGeneratedHeader(StringBuilder code)
{
if (!settings.AddAutoGeneratedHeader)
return;
code.AppendLine("""
// <auto-generated>
// This code was generated by Refitter.
// </auto-generated>

code.AppendLine("// <auto-generated>")
.AppendLine("// This code was generated by Refitter.")
.AppendLine("// </auto-generated>")
.AppendLine();
}
""");
}

private static bool IsHttp(string path)
{
return path.StartsWith("http://") || path.StartsWith("https://");
}
private static bool IsHttp(string path)
{
return path.StartsWith("http://") || path.StartsWith("https://");
}

private static bool IsYaml(string path)
{
return path.EndsWith("yaml") || path.EndsWith("yml");
}
private static bool IsYaml(string path)
{
return path.EndsWith("yaml") || path.EndsWith("yml");
}
}
57 changes: 27 additions & 30 deletions src/Refitter.Core/RefitGeneratorSettings.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;

namespace Refitter.Core
namespace Refitter.Core;

[ExcludeFromCodeCoverage]
public class RefitGeneratorSettings
{
[ExcludeFromCodeCoverage]
public class RefitGeneratorSettings
{
public string OpenApiPath { get; set; } = null!;
public string OpenApiPath { get; set; } = null!;

public string Namespace { get; set; } = "GeneratedCode";

public string Namespace { get; set; } = "GeneratedCode";
public NamingSettings Naming { get; set; } = new();

public NamingSettings Naming { get; set; } = new();
public bool GenerateContracts { get; set; } = true;

public bool GenerateContracts { get; set; } = true;
public bool GenerateXmlDocCodeComments { get; set; } = true;

public bool GenerateXmlDocCodeComments { get; set; } = true;
public bool AddAutoGeneratedHeader { get; set; } = true;

public bool AddAutoGeneratedHeader { get; set; } = true;
public bool ReturnIApiResponse { get; set; }

public bool ReturnIApiResponse { get; set; }

public bool GenerateOperationHeaders { get; set; } = true;
public bool GenerateOperationHeaders { get; set; } = true;

public TypeAccessibility TypeAccessibility { get; set; } = TypeAccessibility.Public;
public TypeAccessibility TypeAccessibility { get; set; } = TypeAccessibility.Public;

public bool UseCancellationTokens { get; set; }
}
public bool UseCancellationTokens { get; set; }
}

[ExcludeFromCodeCoverage]
public class NamingSettings
{
public bool UseOpenApiTitle { get; set; } = true;
[ExcludeFromCodeCoverage]
public class NamingSettings
{
public bool UseOpenApiTitle { get; set; } = true;

public string InterfaceName { get; set; } = "ApiClient";
}
public string InterfaceName { get; set; } = "ApiClient";
}

public enum TypeAccessibility
{
Public,
Internal
}
public enum TypeAccessibility
{
Public,
Internal
}
18 changes: 8 additions & 10 deletions src/Refitter.Core/RefitInterfaceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using NSwag;
using System;
using System.Text;
using NSwag;

namespace Refitter.Core;

Expand All @@ -25,10 +25,12 @@ public RefitInterfaceGenerator(

public string GenerateRefitInterface()
{
var code = new StringBuilder();
code.AppendLine(GenerateInterfaceDeclaration());
code.AppendLine(GenerateInterfaceBody());
return code.ToString();
return $$"""
{{GenerateInterfaceDeclaration()}}
{{Separator}}{
{{GenerateInterfaceBody()}}
{{Separator}}}
""";
}

private string GenerateInterfaceBody()
Expand Down Expand Up @@ -68,7 +70,6 @@ private string GenerateInterfaceBody()
}
}

code.AppendLine($"{Separator}}}");
return code.ToString();
}

Expand Down Expand Up @@ -112,10 +113,7 @@ private string GenerateInterfaceDeclaration()
"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();
return $"{Separator}{modifier} interface I{title.CapitalizeFirstCharacter()}";
}
}