From 0abf72ed2f57b934526e372f6ab2ef2209ca6ed7 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 15 Nov 2022 18:19:05 -0800 Subject: [PATCH] feat: Adds JSON convertibles (#1253) --- .../Json/Converters/JsonDtoConverter.cs | 46 +++++++++++++++++++ .../Converters/JsonDtoConverterFactory.cs | 29 ++++++++++++ .../Json/Converters/Point2DConverter.cs | 3 +- .../Json/Converters/Point3DConverter.cs | 1 + .../Json/Converters/Rectangle3DConverter.cs | 1 + .../Json/Converters/WorldLocationConverter.cs | 1 + Projects/Server/Json/IJsonConvertible.cs | 28 +++++++++++ 7 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 Projects/Server/Json/Converters/JsonDtoConverter.cs create mode 100644 Projects/Server/Json/Converters/JsonDtoConverterFactory.cs create mode 100644 Projects/Server/Json/IJsonConvertible.cs diff --git a/Projects/Server/Json/Converters/JsonDtoConverter.cs b/Projects/Server/Json/Converters/JsonDtoConverter.cs new file mode 100644 index 000000000..c3b7f30a1 --- /dev/null +++ b/Projects/Server/Json/Converters/JsonDtoConverter.cs @@ -0,0 +1,46 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: JsonDtoConverter.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Server.Json; + +public class JsonDtoConverter : JsonConverter + where TDto : IJsonRootDtoConvertible, new() where TObject : new() +{ + public override TObject Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + if (typeof(TObject) != typeToConvert) + { + throw new JsonException($"Invalid object type to deserialize for '{typeof(TObject).Name}'"); + } + + // Deserialize to the DTO + var dto = JsonSerializer.Deserialize(ref reader, options); + + return TDto.ToObject(dto); + } + + public override void Write(Utf8JsonWriter writer, TObject value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, TDto.FromObject(value), options); + } +} diff --git a/Projects/Server/Json/Converters/JsonDtoConverterFactory.cs b/Projects/Server/Json/Converters/JsonDtoConverterFactory.cs new file mode 100644 index 000000000..6d5b9f96c --- /dev/null +++ b/Projects/Server/Json/Converters/JsonDtoConverterFactory.cs @@ -0,0 +1,29 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: JsonDtoConverter.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Server.Json; + +public class JsonDtoConverterFactory : JsonConverterFactory + where TDto : IJsonRootDtoConvertible, new() where TObject : new() +{ + public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TObject); + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => + new JsonDtoConverter(); +} diff --git a/Projects/Server/Json/Converters/Point2DConverter.cs b/Projects/Server/Json/Converters/Point2DConverter.cs index 40293fd0f..e93fe182e 100644 --- a/Projects/Server/Json/Converters/Point2DConverter.cs +++ b/Projects/Server/Json/Converters/Point2DConverter.cs @@ -95,9 +95,10 @@ public class Point2DConverter : JsonConverter public override Point2D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType switch { + JsonTokenType.String => Point2D.Parse(reader.GetString(), null), JsonTokenType.StartArray => DeserializeArray(ref reader), JsonTokenType.StartObject => DeserializeObj(ref reader), - _ => throw new JsonException("Invalid Json for Point3D") + _ => throw new JsonException("Invalid json for Point3D") }; public override void Write(Utf8JsonWriter writer, Point2D value, JsonSerializerOptions options) diff --git a/Projects/Server/Json/Converters/Point3DConverter.cs b/Projects/Server/Json/Converters/Point3DConverter.cs index 5bfcfd24b..663305df9 100644 --- a/Projects/Server/Json/Converters/Point3DConverter.cs +++ b/Projects/Server/Json/Converters/Point3DConverter.cs @@ -96,6 +96,7 @@ public class Point3DConverter : JsonConverter public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType switch { + JsonTokenType.String => Point3D.Parse(reader.GetString(), null), JsonTokenType.StartArray => DeserializeArray(ref reader), JsonTokenType.StartObject => DeserializeObj(ref reader), _ => throw new JsonException("Invalid Json for Point3D") diff --git a/Projects/Server/Json/Converters/Rectangle3DConverter.cs b/Projects/Server/Json/Converters/Rectangle3DConverter.cs index a224c4f67..0a54f2b61 100644 --- a/Projects/Server/Json/Converters/Rectangle3DConverter.cs +++ b/Projects/Server/Json/Converters/Rectangle3DConverter.cs @@ -164,6 +164,7 @@ public class Rectangle3DConverter : JsonConverter public override Rectangle3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType switch { + JsonTokenType.String => Rectangle3D.Parse(reader.GetString(), null), JsonTokenType.StartArray => DeserializeArray(ref reader), JsonTokenType.StartObject => DeserializeObj(ref reader, options), _ => throw new JsonException("Invalid Json for Point3D") diff --git a/Projects/Server/Json/Converters/WorldLocationConverter.cs b/Projects/Server/Json/Converters/WorldLocationConverter.cs index fc328c908..6cf4ad042 100644 --- a/Projects/Server/Json/Converters/WorldLocationConverter.cs +++ b/Projects/Server/Json/Converters/WorldLocationConverter.cs @@ -171,6 +171,7 @@ public class WorldLocationConverter : JsonConverter public override WorldLocation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType switch { + JsonTokenType.String => WorldLocation.Parse(reader.GetString(), null), JsonTokenType.StartArray => DeserializeArray(ref reader), JsonTokenType.StartObject => DeserializeObj(ref reader, options), _ => throw new JsonException("Invalid Json for Point3D") diff --git a/Projects/Server/Json/IJsonConvertible.cs b/Projects/Server/Json/IJsonConvertible.cs new file mode 100644 index 000000000..258eafcc9 --- /dev/null +++ b/Projects/Server/Json/IJsonConvertible.cs @@ -0,0 +1,28 @@ +/************************************************************************* + * ModernUO * + * Copyright 2019-2022 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: IJsonConvertible.cs * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Json; + +public interface IJsonRootDtoConvertible where TSelf : IJsonRootDtoConvertible where TObject : new() +{ + public abstract static TSelf FromObject(TObject obj); + public abstract static TObject ToObject(TSelf obj); +} + +public interface IJsonDtoConvertible where TSelf : IJsonDtoConvertible where TObject : new() +{ + public abstract TSelf HydrateDto(TObject obj); + public abstract TObject HydrateObject(TObject obj); +}