aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNiels van Velzen <nielsvanvelzen@users.noreply.github.com>2024-03-05 00:44:54 +0100
committerGitHub <noreply@github.com>2024-03-04 16:44:54 -0700
commit407cf5d0bf9d3563ae77fd34ce29ffae5af4339f (patch)
tree2640dfb680cc4f302ec2dbeeb2a7cd9536005b80 /src
parent83d2bc3f9f13c62f6d3ef16c4fe75f0f5a18110d (diff)
Add MediaStreamProtocol enum (#10153)
* Add MediaStreamProtocol enum * Add default handling for enum during deserialization --------- Co-authored-by: Cody Robibero <cody@robibe.ro>
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverter.cs49
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverterFactory.cs31
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonGuidConverter.cs2
-rw-r--r--src/Jellyfin.Extensions/Json/Converters/JsonNullableStructConverter.cs5
-rw-r--r--src/Jellyfin.Extensions/Json/JsonDefaults.cs1
-rw-r--r--src/Jellyfin.Extensions/Json/Utf8JsonExtensions.cs27
6 files changed, 110 insertions, 5 deletions
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverter.cs
new file mode 100644
index 000000000..06ecfc558
--- /dev/null
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverter.cs
@@ -0,0 +1,49 @@
+using System;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Jellyfin.Extensions.Json.Converters;
+
+/// <summary>
+/// Json unknown enum converter.
+/// </summary>
+/// <typeparam name="T">The type of enum.</typeparam>
+public class JsonDefaultStringEnumConverter<T> : JsonConverter<T>
+ where T : struct, Enum
+{
+ private readonly JsonConverter<T> _baseConverter;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonDefaultStringEnumConverter{T}"/> class.
+ /// </summary>
+ /// <param name="baseConverter">The base json converter.</param>
+ public JsonDefaultStringEnumConverter(JsonConverter<T> baseConverter)
+ {
+ _baseConverter = baseConverter;
+ }
+
+ /// <inheritdoc />
+ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.IsNull() || reader.IsEmptyString())
+ {
+ var customValueAttribute = typeToConvert.GetCustomAttribute<DefaultValueAttribute>();
+ if (customValueAttribute?.Value is null)
+ {
+ throw new InvalidOperationException($"Default value not set for '{typeToConvert.Name}'");
+ }
+
+ return (T)customValueAttribute.Value;
+ }
+
+ return _baseConverter.Read(ref reader, typeToConvert, options);
+ }
+
+ /// <inheritdoc />
+ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
+ {
+ _baseConverter.Write(writer, value, options);
+ }
+}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverterFactory.cs b/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverterFactory.cs
new file mode 100644
index 000000000..5a9bf546e
--- /dev/null
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonDefaultStringEnumConverterFactory.cs
@@ -0,0 +1,31 @@
+using System;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Jellyfin.Extensions.Json.Converters;
+
+/// <summary>
+/// Utilizes the JsonStringEnumConverter and sets a default value if not provided.
+/// </summary>
+public class JsonDefaultStringEnumConverterFactory : JsonConverterFactory
+{
+ private static readonly JsonStringEnumConverter _baseConverterFactory = new();
+
+ /// <inheritdoc />
+ public override bool CanConvert(Type typeToConvert)
+ {
+ return _baseConverterFactory.CanConvert(typeToConvert)
+ && typeToConvert.IsDefined(typeof(DefaultValueAttribute));
+ }
+
+ /// <inheritdoc />
+ public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+ {
+ var baseConverter = _baseConverterFactory.CreateConverter(typeToConvert, options);
+ var converterType = typeof(JsonDefaultStringEnumConverter<>).MakeGenericType(typeToConvert);
+
+ return (JsonConverter?)Activator.CreateInstance(converterType, baseConverter);
+ }
+}
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonGuidConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonGuidConverter.cs
index ea6d141cb..2964c6943 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonGuidConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonGuidConverter.cs
@@ -12,7 +12,7 @@ namespace Jellyfin.Extensions.Json.Converters
{
/// <inheritdoc />
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- => reader.TokenType == JsonTokenType.Null
+ => reader.IsNull()
? Guid.Empty
: ReadInternal(ref reader);
diff --git a/src/Jellyfin.Extensions/Json/Converters/JsonNullableStructConverter.cs b/src/Jellyfin.Extensions/Json/Converters/JsonNullableStructConverter.cs
index 28437023f..94004fa49 100644
--- a/src/Jellyfin.Extensions/Json/Converters/JsonNullableStructConverter.cs
+++ b/src/Jellyfin.Extensions/Json/Converters/JsonNullableStructConverter.cs
@@ -15,10 +15,7 @@ namespace Jellyfin.Extensions.Json.Converters
/// <inheritdoc />
public override TStruct? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
- // Token is empty string.
- if (reader.TokenType == JsonTokenType.String
- && ((reader.HasValueSequence && reader.ValueSequence.IsEmpty)
- || (!reader.HasValueSequence && reader.ValueSpan.IsEmpty)))
+ if (reader.IsEmptyString())
{
return null;
}
diff --git a/src/Jellyfin.Extensions/Json/JsonDefaults.cs b/src/Jellyfin.Extensions/Json/JsonDefaults.cs
index 9e6d4c3f8..cbe5849ec 100644
--- a/src/Jellyfin.Extensions/Json/JsonDefaults.cs
+++ b/src/Jellyfin.Extensions/Json/JsonDefaults.cs
@@ -38,6 +38,7 @@ namespace Jellyfin.Extensions.Json
new JsonNullableGuidConverter(),
new JsonVersionConverter(),
new JsonFlagEnumConverterFactory(),
+ new JsonDefaultStringEnumConverterFactory(),
new JsonStringEnumConverter(),
new JsonNullableStructConverterFactory(),
new JsonDateTimeConverter(),
diff --git a/src/Jellyfin.Extensions/Json/Utf8JsonExtensions.cs b/src/Jellyfin.Extensions/Json/Utf8JsonExtensions.cs
new file mode 100644
index 000000000..d06508a26
--- /dev/null
+++ b/src/Jellyfin.Extensions/Json/Utf8JsonExtensions.cs
@@ -0,0 +1,27 @@
+using System.Text.Json;
+
+namespace Jellyfin.Extensions.Json;
+
+/// <summary>
+/// Extensions for Utf8JsonReader and Utf8JsonWriter.
+/// </summary>
+public static class Utf8JsonExtensions
+{
+ /// <summary>
+ /// Determines if the reader contains an empty string.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ /// <returns>Whether the reader contains an empty string.</returns>
+ public static bool IsEmptyString(this Utf8JsonReader reader)
+ => reader.TokenType == JsonTokenType.String
+ && ((reader.HasValueSequence && reader.ValueSequence.IsEmpty)
+ || (!reader.HasValueSequence && reader.ValueSpan.IsEmpty));
+
+ /// <summary>
+ /// Determines if the reader contains a null value.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ /// <returns>Whether the reader contains null.</returns>
+ public static bool IsNull(this Utf8JsonReader reader)
+ => reader.TokenType == JsonTokenType.Null;
+}