Skip to content

Commit 8a861c9

Browse files
committed
feat: Add writer settings to enable sorting collections using a comparer
1 parent 1b4ad07 commit 8a861c9

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Microsoft.OpenApi.Extensions
6+
{
7+
/// <summary>
8+
/// Dictionary extension methods
9+
/// </summary>
10+
public static class DictionaryExtensions
11+
{
12+
/// <summary>
13+
/// Returns a new dictionary with entries sorted by key using the default comparer.
14+
/// </summary>
15+
public static IDictionary<TKey, TValue> Sort<TKey, TValue>(
16+
this IDictionary<TKey, TValue> source)
17+
where TKey : notnull
18+
{
19+
#if NET7_0_OR_GREATER
20+
ArgumentNullException.ThrowIfNull(nameof(source));
21+
#else
22+
if (source == null)
23+
throw new ArgumentNullException(nameof(source));
24+
#endif
25+
26+
return source.OrderBy(kvp => kvp.Key)
27+
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
28+
}
29+
30+
/// <summary>
31+
/// Returns a new dictionary with entries sorted by key using a custom comparer.
32+
/// </summary>
33+
public static IDictionary<TKey, TValue> Sort<TKey, TValue>(
34+
this IDictionary<TKey, TValue> source,
35+
IComparer<TKey> comparer)
36+
where TKey : notnull
37+
{
38+
#if NET7_0_OR_GREATER
39+
ArgumentNullException.ThrowIfNull(nameof(source));
40+
ArgumentNullException.ThrowIfNull(nameof(comparer));
41+
#else
42+
if (source == null)
43+
throw new ArgumentNullException(nameof(source));
44+
if (comparer == null)
45+
throw new ArgumentNullException(nameof(comparer));
46+
#endif
47+
return source.OrderBy(kvp => kvp.Key, comparer)
48+
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
49+
}
50+
}
51+
}

src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.Generic;
77
using System.Linq;
88
using System.Text.Json.Nodes;
9+
using Microsoft.OpenApi.Extensions;
910
using Microsoft.OpenApi.Interfaces;
1011

1112
namespace Microsoft.OpenApi.Writers
@@ -458,6 +459,17 @@ private static void WriteMapInternal<T>(
458459

459460
if (elements != null)
460461
{
462+
var settings = writer.GetSettings();
463+
464+
if (settings?.EnableSorting == true)
465+
{
466+
elements = elements.Sort(); // sort with default comparer
467+
}
468+
else if (settings?.KeyComparer != null)
469+
{
470+
elements = elements.Sort(settings.KeyComparer); // sort using custom comparer
471+
}
472+
461473
foreach (var item in elements)
462474
{
463475
writer.WritePropertyName(item.Key);

src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using Microsoft.OpenApi.Models;
23
using Microsoft.OpenApi.Services;
34

@@ -24,5 +25,15 @@ internal bool ShouldInlineReference(OpenApiReference reference)
2425
return (reference.IsLocal && InlineLocalReferences)
2526
|| (reference.IsExternal && InlineExternalReferences);
2627
}
28+
29+
/// <summary>
30+
/// Enables sorting of collections using the default comparer
31+
/// </summary>
32+
public bool EnableSorting { get; set; }
33+
34+
/// <summary>
35+
/// Custom comparer for sorting collections.
36+
/// </summary>
37+
public IComparer<string>? KeyComparer { get; set; }
2738
}
2839
}

0 commit comments

Comments
 (0)