Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Globalization;
Expand All @@ -21,12 +21,28 @@ public static class OpenApiSerializableExtensions
/// <param name="stream">The output stream.</param>
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="cancellationToken">The cancellation token.</param>
#pragma warning disable RS0027 // The settings overload below has the same parameter count but different types; no ambiguity exists.
public static Task SerializeAsJsonAsync<T>(this T element, Stream stream, OpenApiSpecVersion specVersion, CancellationToken cancellationToken = default)
#pragma warning restore RS0027
Comment on lines +24 to +26
where T : IOpenApiSerializable
{
return element.SerializeAsync(stream, specVersion, OpenApiConstants.Json, cancellationToken);
}

/// <summary>
/// Serialize the <see cref="IOpenApiSerializable"/> to the Open API document (JSON) using the given stream, specification version and settings.
/// </summary>
/// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam>
/// <param name="element">The Open API element.</param>
/// <param name="stream">The output stream.</param>
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="settings">Settings controlling JSON output, including <see cref="OpenApiJsonWriterSettings.Terse"/> for compact formatting.</param>
public static Task SerializeAsJsonAsync<T>(this T element, Stream stream, OpenApiSpecVersion specVersion, OpenApiJsonWriterSettings settings)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should also accept a cancellation token

where T : IOpenApiSerializable
{
return element.SerializeAsync(stream, specVersion, OpenApiConstants.Json, settings, CancellationToken.None);
}

/// <summary>
/// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document (YAML) using the given stream and specification version.
/// </summary>
Expand Down Expand Up @@ -104,7 +120,9 @@ public static Task SerializeAsync<T>(
/// <param name="writer">The output writer.</param>
/// <param name="specVersion">Version of the specification the output should conform to</param>
/// <param name="cancellationToken">The cancellation token.</param>
#pragma warning disable RS0027 // The settings-bearing SerializeAsync overloads below have the same parameter count but different types; no ambiguity exists.
public static Task SerializeAsync<T>(this T element, IOpenApiWriter writer, OpenApiSpecVersion specVersion, CancellationToken cancellationToken = default)
#pragma warning restore RS0027
where T : IOpenApiSerializable
Comment on lines +123 to 126
{
Utils.CheckArgumentNull(element);
Expand Down Expand Up @@ -142,15 +160,33 @@ public static Task SerializeAsync<T>(this T element, IOpenApiWriter writer, Open
/// <param name="element">The Open API element.</param>
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="cancellationToken">The cancellation token.</param>
#pragma warning disable RS0027 // The settings overload below has the same parameter count but different types; no ambiguity exists.
public static Task<string> SerializeAsJsonAsync<T>(
this T element,
OpenApiSpecVersion specVersion,
CancellationToken cancellationToken = default)
#pragma warning restore RS0027
where T : IOpenApiSerializable
{
return element.SerializeAsync(specVersion, OpenApiConstants.Json, cancellationToken);
}

/// <summary>
/// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document as a string in JSON format using the given settings.
/// </summary>
/// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam>
/// <param name="element">The Open API element.</param>
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="settings">Settings controlling JSON output, including <see cref="OpenApiJsonWriterSettings.Terse"/> for compact formatting.</param>
public static Task<string> SerializeAsJsonAsync<T>(
this T element,
OpenApiSpecVersion specVersion,
OpenApiJsonWriterSettings settings)
where T : IOpenApiSerializable
{
return element.SerializeAsync(specVersion, OpenApiConstants.Json, settings);
}

/// <summary>
/// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document as a string in YAML format.
/// </summary>
Expand All @@ -175,11 +211,13 @@ public static Task<string> SerializeAsYamlAsync<T>(
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="format">Open API document format.</param>
/// <param name="cancellationToken">The cancellation token.</param>
#pragma warning disable RS0027 // The settings overload below has the same parameter count but different types; no ambiguity exists.
public static async Task<string> SerializeAsync<T>(
this T element,
OpenApiSpecVersion specVersion,
string format,
CancellationToken cancellationToken = default)
#pragma warning restore RS0027
where T : IOpenApiSerializable
{
Utils.CheckArgumentNull(element);
Expand All @@ -195,5 +233,30 @@ public static async Task<string> SerializeAsync<T>(
return await streamReader.ReadToEndAsync().ConfigureAwait(false);
#endif
}

/// <summary>
/// Serializes the <see cref="IOpenApiSerializable"/> to the Open API document as a string in the given format using the given settings.
/// </summary>
/// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam>
/// <param name="element">The Open API element.</param>
/// <param name="specVersion">The Open API specification version.</param>
/// <param name="format">Open API document format.</param>
/// <param name="settings">Provide configuration settings for controlling writing output.</param>
public static async Task<string> SerializeAsync<T>(
this T element,
OpenApiSpecVersion specVersion,
string format,
OpenApiWriterSettings? settings)
where T : IOpenApiSerializable
{
Utils.CheckArgumentNull(element);

using var stream = new MemoryStream();
await element.SerializeAsync(stream, specVersion, format, settings, CancellationToken.None).ConfigureAwait(false);
stream.Position = 0;

using var streamReader = new StreamReader(stream);
return await streamReader.ReadToEndAsync().ConfigureAwait(false);
}
}
}
3 changes: 3 additions & 0 deletions src/Microsoft.OpenApi/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#nullable enable
const Microsoft.OpenApi.OpenApiConstants.JsonSchemaExamplesExtension = "x-jsonschema-examples" -> string!
const Microsoft.OpenApi.OpenApiConstants.OaiLicenseIdentifier = "x-oai-license-identifier" -> string!
static Microsoft.OpenApi.OpenApiSerializableExtensions.SerializeAsJsonAsync<T>(this T element, Microsoft.OpenApi.OpenApiSpecVersion specVersion, Microsoft.OpenApi.OpenApiJsonWriterSettings! settings) -> System.Threading.Tasks.Task<string!>!
static Microsoft.OpenApi.OpenApiSerializableExtensions.SerializeAsJsonAsync<T>(this T element, System.IO.Stream! stream, Microsoft.OpenApi.OpenApiSpecVersion specVersion, Microsoft.OpenApi.OpenApiJsonWriterSettings! settings) -> System.Threading.Tasks.Task!
static Microsoft.OpenApi.OpenApiSerializableExtensions.SerializeAsync<T>(this T element, Microsoft.OpenApi.OpenApiSpecVersion specVersion, string! format, Microsoft.OpenApi.OpenApiWriterSettings? settings) -> System.Threading.Tasks.Task<string!>!
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,60 @@ public async Task UsesTheTerseOutputInformationFromSettingsNoSettings()

Assert.Equal("{\n \"name\": \"param1\",\n \"in\": \"query\",\n \"description\": \"A sample parameter\",\n \"schema\": {\n \"type\": \"string\"\n }\n}", output);
}

[Fact]
public async Task SerializeAsJsonAsync_WithTerseSettings_WritesToStream()
{
var parameter = new OpenApiParameter
{
Name = "param1",
In = ParameterLocation.Query,
Schema = new OpenApiSchema { Type = JsonSchemaType.String }
};

var settings = new OpenApiJsonWriterSettings { Terse = true };

using var stream = new MemoryStream();
await parameter.SerializeAsJsonAsync(stream, OpenApiSpecVersion.OpenApi3_1, settings);

stream.Position = 0;
using var reader = new StreamReader(stream);
var output = await reader.ReadToEndAsync();

Assert.Equal("{\"name\":\"param1\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}}", output);
}

[Fact]
public async Task SerializeAsJsonAsync_WithTerseSettings_ReturnsCompactString()
{
var parameter = new OpenApiParameter
{
Name = "param1",
In = ParameterLocation.Query,
Schema = new OpenApiSchema { Type = JsonSchemaType.String }
};

var settings = new OpenApiJsonWriterSettings { Terse = true };

var output = await parameter.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1, settings);

Assert.Equal("{\"name\":\"param1\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}}", output);
}

[Fact]
public async Task SerializeAsync_WithSettings_ReturnsFormattedString()
{
var parameter = new OpenApiParameter
{
Name = "param1",
In = ParameterLocation.Query,
Schema = new OpenApiSchema { Type = JsonSchemaType.String }
};

var settings = new OpenApiJsonWriterSettings { Terse = false };

var output = await parameter.SerializeAsync(OpenApiSpecVersion.OpenApi3_1, OpenApiConstants.Json, settings);

Assert.Equal("{\n \"name\": \"param1\",\n \"in\": \"query\",\n \"schema\": {\n \"type\": \"string\"\n }\n}", output);
}
}