Skip to content

Commit

Permalink
Core - Replaced JSON.NET with System.Text.Json
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertBeekman committed Feb 26, 2024
1 parent e112ca9 commit 6d8572c
Show file tree
Hide file tree
Showing 53 changed files with 282 additions and 479 deletions.
2 changes: 1 addition & 1 deletion src/Artemis.Core/Artemis.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@
<PackageReference Include="Humanizer.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="McMaster.NETCore.Plugins" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="RGB.NET.Core" />
<PackageReference Include="RGB.NET.Layout" />
<PackageReference Include="RGB.NET.Presets" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.Debug" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="SkiaSharp" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>

<ItemGroup>
Expand Down
18 changes: 5 additions & 13 deletions src/Artemis.Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using Artemis.Core.JsonConverters;
using Artemis.Core.Services;
using Artemis.Core.SkiaSharp;
using Newtonsoft.Json;

namespace Artemis.Core;

Expand Down Expand Up @@ -62,7 +60,7 @@ public static class Constants
/// The full path to the Artemis user layouts folder
/// </summary>
public static readonly string LayoutsFolder = Path.Combine(DataFolder, "User Layouts");

/// <summary>
/// The full path to the Artemis user layouts folder
/// </summary>
Expand Down Expand Up @@ -97,17 +95,11 @@ public static class Constants
internal static readonly CorePluginFeature CorePluginFeature = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Core")};
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Effect Placeholder")};

internal static JsonSerializerSettings JsonConvertSettings = new()
internal static JsonSerializerOptions JsonConvertSettings = new()
{
Converters = new List<JsonConverter> {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()}
Converters = {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()}
};

internal static JsonSerializerSettings JsonConvertTypedSettings = new()
{
TypeNameHandling = TypeNameHandling.All,
Converters = new List<JsonConverter> {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()}
};


/// <summary>
/// A read-only collection containing all primitive numeric types
/// </summary>
Expand Down
48 changes: 25 additions & 23 deletions src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Artemis.Core.JsonConverters;

/// <summary>
/// An int converter that, if required, will round float values
/// </summary>
internal class ForgivingIntConverter : JsonConverter<int>
namespace Artemis.Core.JsonConverters
{
public override bool CanWrite => false;

public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
/// <summary>
/// An int converter that, if required, will round float values
/// </summary>
internal class ForgivingIntConverter : JsonConverter<int>
{
throw new NotImplementedException();
}
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
throw new JsonException("Cannot convert null value.");

public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JValue? jsonValue = serializer.Deserialize<JValue>(reader);
if (jsonValue == null)
throw new JsonReaderException("Failed to deserialize forgiving int value");
if (reader.TokenType == JsonTokenType.Number)
{
if (reader.TryGetInt32(out int intValue))
return intValue;

if (reader.TryGetDouble(out double doubleValue))
return (int)Math.Round(doubleValue);
}

if (jsonValue.Type == JTokenType.Float)
return (int) Math.Round(jsonValue.Value<double>());
if (jsonValue.Type == JTokenType.Integer)
return jsonValue.Value<int>();
throw new JsonException("Failed to deserialize forgiving int value");
}

throw new JsonReaderException("Failed to deserialize forgiving int value");
public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
26 changes: 0 additions & 26 deletions src/Artemis.Core/JsonConverters/ForgivingVersionConverter.cs

This file was deleted.

36 changes: 19 additions & 17 deletions src/Artemis.Core/JsonConverters/NumericJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Artemis.Core.JsonConverters;

internal class NumericJsonConverter : JsonConverter<Numeric>
namespace Artemis.Core.JsonConverters
{
#region Overrides of JsonConverter<Numeric>

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, Numeric value, JsonSerializer serializer)
internal class NumericJsonConverter : JsonConverter<Numeric>
{
float floatValue = value;
writer.WriteValue(floatValue);
}
public override void Write(Utf8JsonWriter writer, Numeric value, JsonSerializerOptions options)
{
float floatValue = value;
writer.WriteNumberValue(floatValue);
}

/// <inheritdoc />
public override Numeric ReadJson(JsonReader reader, Type objectType, Numeric existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return new Numeric(reader.Value);
}
public override Numeric Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.Number)
{
throw new JsonException($"Expected a number token, but got {reader.TokenType}.");
}

#endregion
float floatValue = reader.GetSingle();
return new Numeric(floatValue);
}
}
}
29 changes: 17 additions & 12 deletions src/Artemis.Core/JsonConverters/SKColorConverter.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using SkiaSharp;

namespace Artemis.Core.JsonConverters;

internal class SKColorConverter : JsonConverter<SKColor>
namespace Artemis.Core.JsonConverters
{
public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer)
internal class SKColorConverter : JsonConverter<SKColor>
{
writer.WriteValue(value.ToString());
}
public override void Write(Utf8JsonWriter writer, SKColor value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}

public override SKColor ReadJson(JsonReader reader, Type objectType, SKColor existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.Value is string value && !string.IsNullOrWhiteSpace(value))
return SKColor.Parse(value);
public override SKColor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException($"Expected a string token, but got {reader.TokenType}.");
}

return SKColor.Empty;
string colorString = reader.GetString() ?? string.Empty;
return SKColor.TryParse(colorString, out SKColor color) ? color : SKColor.Empty;
}
}
}
49 changes: 18 additions & 31 deletions src/Artemis.Core/JsonConverters/StreamConverter.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,31 @@
using System;
using System.IO;
using Newtonsoft.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Artemis.Core.JsonConverters;

/// <inheritdoc />
public class StreamConverter : JsonConverter<Stream>
namespace Artemis.Core.JsonConverters
{
#region Overrides of JsonConverter<Stream>

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, Stream? value, JsonSerializer serializer)
internal class StreamConverter : JsonConverter<Stream>
{
if (value == null)
public override void Write(Utf8JsonWriter writer, Stream value, JsonSerializerOptions options)
{
writer.WriteNull();
return;
using MemoryStream memoryStream = new();
value.Position = 0;
value.CopyTo(memoryStream);
writer.WriteBase64StringValue(memoryStream.ToArray());
}

using MemoryStream memoryStream = new();
value.Position = 0;
value.CopyTo(memoryStream);
writer.WriteValue(memoryStream.ToArray());
}
public override Stream Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
throw new JsonException($"Expected a string token, but got {reader.TokenType}.");

/// <inheritdoc />
public override Stream? ReadJson(JsonReader reader, Type objectType, Stream? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.Value is not string base64)
return null;
string base64 = reader.GetString() ?? string.Empty;

if (existingValue == null || !hasExistingValue || !existingValue.CanRead)
return new MemoryStream(Convert.FromBase64String(base64));
if (typeToConvert == typeof(MemoryStream))
return new MemoryStream(Convert.FromBase64String(base64));

using MemoryStream memoryStream = new(Convert.FromBase64String(base64));
existingValue.Position = 0;
memoryStream.CopyTo(existingValue);
existingValue.Position = 0;
return existingValue;
throw new InvalidOperationException("StreamConverter only supports reading to MemoryStream");
}
}

#endregion
}
2 changes: 1 addition & 1 deletion src/Artemis.Core/Models/Profile/Folder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public Folder CreateCopy()
if (Parent == null)
throw new ArtemisCoreException("Cannot create a copy of a folder without a parent");

FolderEntity entityCopy = CoreJson.DeserializeObject<FolderEntity>(CoreJson.SerializeObject(FolderEntity, true), true)!;
FolderEntity entityCopy = CoreJson.DeserializeObject<FolderEntity>(CoreJson.SerializeObject(FolderEntity))!;
entityCopy.Id = Guid.NewGuid();
entityCopy.Name += " - Copy";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.Json;
using Artemis.Storage.Entities.Profile;
using Newtonsoft.Json;

namespace Artemis.Core;

Expand Down Expand Up @@ -324,7 +324,7 @@ public void ApplyDefaultValue()
// Reference types make a deep clone (ab)using JSON
else
{
string json = CoreJson.SerializeObject(DefaultValue, true);
string json = CoreJson.SerializeObject(DefaultValue);
SetCurrentValue(CoreJson.DeserializeObject<T>(json)!);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.IO;
using System.Text.Json.Serialization;
using Artemis.Core.JsonConverters;
using Artemis.Storage.Entities.Profile;
using Newtonsoft.Json;

namespace Artemis.Core;

Expand All @@ -19,7 +19,7 @@ public class ProfileConfigurationExportModel : IDisposable
/// <summary>
/// Gets or sets the storage entity of the profile
/// </summary>
[JsonProperty(Required = Required.Always)]
[JsonRequired]
public ProfileEntity ProfileEntity { get; set; } = null!;

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Artemis.Core/Plugins/Modules/DataModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text.Json.Serialization;
using Humanizer;
using Newtonsoft.Json;

namespace Artemis.Core.Modules;

Expand Down
5 changes: 0 additions & 5 deletions src/Artemis.Core/Plugins/PluginFeatureInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
using System.Linq;
using Artemis.Storage.Entities.Plugins;
using Humanizer;
using Newtonsoft.Json;

namespace Artemis.Core;

/// <summary>
/// Represents basic info about a plugin feature and contains a reference to the instance of said feature
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
{
private string? _description;
Expand Down Expand Up @@ -64,7 +62,6 @@ public Exception? LoadException
/// <summary>
/// The name of the feature
/// </summary>
[JsonProperty(Required = Required.Always)]
public string Name
{
get => _name;
Expand All @@ -74,7 +71,6 @@ public string Name
/// <summary>
/// A short description of the feature
/// </summary>
[JsonProperty]
public string? Description
{
get => _description;
Expand All @@ -85,7 +81,6 @@ public string? Description
/// Marks the feature to always be enabled as long as the plugin is enabled and cannot be disabled.
/// <para>Note: always <see langword="true" /> if this is the plugin's only feature</para>
/// </summary>
[JsonProperty]
public bool AlwaysEnabled { get; internal set; }

/// <summary>
Expand Down
Loading

0 comments on commit 6d8572c

Please sign in to comment.