From 454a2de2949deae90de4a936fb8fa7341d4a2990 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 20 Jan 2018 21:45:21 -0500 Subject: [PATCH] split SFieldConverter into separate converters --- src/SMAPI/Framework/Models/Manifest.cs | 9 +- src/SMAPI/Framework/Models/ModDataRecord.cs | 7 +- .../Converters/SFieldConverter.cs | 121 ------------------ .../ColorConverter.cs | 2 +- .../PointConverter.cs | 2 +- .../RectangleConverter.cs | 2 +- .../Framework/Serialisation/JsonHelper.cs | 3 +- .../ManifestDependencyArrayConverter.cs | 60 +++++++++ .../ModCompatibilityArrayConverter.cs | 61 +++++++++ .../SmapiConverters/ModDataIdConverter.cs | 19 +++ .../SemanticVersionConverter.cs | 36 ++++++ .../StringEnumConverter.cs | 2 +- src/SMAPI/StardewModdingAPI.csproj | 13 +- 13 files changed, 197 insertions(+), 140 deletions(-) delete mode 100644 src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs rename src/SMAPI/Framework/Serialisation/{Converters => CrossplatformConverters}/ColorConverter.cs (95%) rename src/SMAPI/Framework/Serialisation/{Converters => CrossplatformConverters}/PointConverter.cs (95%) rename src/SMAPI/Framework/Serialisation/{Converters => CrossplatformConverters}/RectangleConverter.cs (96%) create mode 100644 src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs create mode 100644 src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs create mode 100644 src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs create mode 100644 src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs rename src/SMAPI/Framework/Serialisation/{Converters => SmapiConverters}/StringEnumConverter.cs (91%) diff --git a/src/SMAPI/Framework/Models/Manifest.cs b/src/SMAPI/Framework/Models/Manifest.cs index c362be9b..f9762406 100644 --- a/src/SMAPI/Framework/Models/Manifest.cs +++ b/src/SMAPI/Framework/Models/Manifest.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Models { @@ -21,18 +20,18 @@ namespace StardewModdingAPI.Framework.Models public string Author { get; set; } /// The mod version. - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion Version { get; set; } /// The minimum SMAPI version required by this mod, if any. - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion MinimumApiVersion { get; set; } /// The name of the DLL in the directory that has the method. public string EntryDll { get; set; } /// The other mods that must be loaded before this mod. - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ManifestDependencyArrayConverter))] public IManifestDependency[] Dependencies { get; set; } /// The namespaced mod IDs to query for updates (like Nexus:541). diff --git a/src/SMAPI/Framework/Models/ModDataRecord.cs b/src/SMAPI/Framework/Models/ModDataRecord.cs index fa6fc68d..580acb70 100644 --- a/src/SMAPI/Framework/Models/ModDataRecord.cs +++ b/src/SMAPI/Framework/Models/ModDataRecord.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Models { @@ -13,7 +12,7 @@ namespace StardewModdingAPI.Framework.Models ** Accessors *********/ /// The unique mod identifier. - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ModDataIdConverter))] public ModDataID ID { get; set; } /// A value to inject into field if it's not already set. @@ -23,7 +22,7 @@ namespace StardewModdingAPI.Framework.Models public string AlternativeUrl { get; set; } /// The compatibility of given mod versions (if any). - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ModCompatibilityArrayConverter))] public ModCompatibility[] Compatibility { get; set; } = new ModCompatibility[0]; /// Map local versions to a semantic version for update checks. diff --git a/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs b/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs deleted file mode 100644 index 69353491..00000000 --- a/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using StardewModdingAPI.Framework.Exceptions; -using StardewModdingAPI.Framework.Models; - -namespace StardewModdingAPI.Framework.Serialisation.Converters -{ - /// Overrides how SMAPI reads and writes and fields. - internal class SFieldConverter : JsonConverter - { - /********* - ** Accessors - *********/ - /// Whether this converter can write JSON. - public override bool CanWrite => false; - - - /********* - ** Public methods - *********/ - /// Get whether this instance can convert the specified object type. - /// The object type. - public override bool CanConvert(Type objectType) - { - return - objectType == typeof(ISemanticVersion) - || objectType == typeof(IManifestDependency[]) - || objectType == typeof(ModDataID) - || objectType == typeof(ModCompatibility[]); - } - - /// Reads the JSON representation of the object. - /// The JSON reader. - /// The object type. - /// The object being read. - /// The calling serializer. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - // semantic version - if (objectType == typeof(ISemanticVersion)) - { - JToken token = JToken.Load(reader); - switch (token.Type) - { - case JTokenType.Object: - { - JObject obj = (JObject)token; - int major = obj.Value(nameof(ISemanticVersion.MajorVersion)); - int minor = obj.Value(nameof(ISemanticVersion.MinorVersion)); - int patch = obj.Value(nameof(ISemanticVersion.PatchVersion)); - string build = obj.Value(nameof(ISemanticVersion.Build)); - return new LegacyManifestVersion(major, minor, patch, build); - } - - case JTokenType.String: - { - string str = token.Value(); - if (string.IsNullOrWhiteSpace(str)) - return null; - if (!SemanticVersion.TryParse(str, out ISemanticVersion version)) - throw new SParseException($"Can't parse semantic version from invalid value '{str}', should be formatted like 1.2, 1.2.30, or 1.2.30-beta."); - return version; - } - - default: - throw new SParseException($"Can't parse semantic version from {token.Type}, must be an object or string."); - } - } - - // manifest dependencies - if (objectType == typeof(IManifestDependency[])) - { - List result = new List(); - foreach (JObject obj in JArray.Load(reader).Children()) - { - string uniqueID = obj.Value(nameof(IManifestDependency.UniqueID)); - string minVersion = obj.Value(nameof(IManifestDependency.MinimumVersion)); - bool required = obj.Value(nameof(IManifestDependency.IsRequired)) ?? true; - result.Add(new ManifestDependency(uniqueID, minVersion, required)); - } - return result.ToArray(); - } - - // mod data ID - if (objectType == typeof(ModDataID)) - { - JToken token = JToken.Load(reader); - return new ModDataID(token.Value()); - } - - // mod compatibility records - if (objectType == typeof(ModCompatibility[])) - { - List result = new List(); - foreach (JProperty property in JObject.Load(reader).Properties()) - { - string range = property.Name; - ModStatus status = (ModStatus)Enum.Parse(typeof(ModStatus), property.Value.Value(nameof(ModCompatibility.Status))); - string reasonPhrase = property.Value.Value(nameof(ModCompatibility.ReasonPhrase)); - - result.Add(new ModCompatibility(range, status, reasonPhrase)); - } - return result.ToArray(); - } - - // unknown - throw new NotSupportedException($"Unknown type '{objectType?.FullName}'."); - } - - /// Writes the JSON representation of the object. - /// The JSON writer. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new InvalidOperationException("This converter does not write JSON."); - } - } -} diff --git a/src/SMAPI/Framework/Serialisation/Converters/ColorConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/ColorConverter.cs similarity index 95% rename from src/SMAPI/Framework/Serialisation/Converters/ColorConverter.cs rename to src/SMAPI/Framework/Serialisation/CrossplatformConverters/ColorConverter.cs index 7f830a0e..f4a2a26e 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/ColorConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/ColorConverter.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// Handles deserialisation of for crossplatform compatibility. /// diff --git a/src/SMAPI/Framework/Serialisation/Converters/PointConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/PointConverter.cs similarity index 95% rename from src/SMAPI/Framework/Serialisation/Converters/PointConverter.cs rename to src/SMAPI/Framework/Serialisation/CrossplatformConverters/PointConverter.cs index 87d0ff34..84c70989 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/PointConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/PointConverter.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// Handles deserialisation of for crossplatform compatibility. /// diff --git a/src/SMAPI/Framework/Serialisation/Converters/RectangleConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/RectangleConverter.cs similarity index 96% rename from src/SMAPI/Framework/Serialisation/Converters/RectangleConverter.cs rename to src/SMAPI/Framework/Serialisation/CrossplatformConverters/RectangleConverter.cs index 7cf912a7..b89551e3 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/RectangleConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/RectangleConverter.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// Handles deserialisation of for crossplatform compatibility. /// diff --git a/src/SMAPI/Framework/Serialisation/JsonHelper.cs b/src/SMAPI/Framework/Serialisation/JsonHelper.cs index 1253f242..2e2a666e 100644 --- a/src/SMAPI/Framework/Serialisation/JsonHelper.cs +++ b/src/SMAPI/Framework/Serialisation/JsonHelper.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework.Input; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.CrossplatformConverters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Serialisation { diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs new file mode 100644 index 00000000..6352e367 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// Handles deserialisation of arrays. + internal class ManifestDependencyArrayConverter : JsonConverter + { + /********* + ** Accessors + *********/ + /// Whether this converter can write JSON. + public override bool CanWrite => false; + + + /********* + ** Public methods + *********/ + /// Get whether this instance can convert the specified object type. + /// The object type. + public override bool CanConvert(Type objectType) + { + return objectType == typeof(IManifestDependency[]); + } + + + /********* + ** Protected methods + *********/ + /// Read the JSON representation of the object. + /// The JSON reader. + /// The object type. + /// The object being read. + /// The calling serializer. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List result = new List(); + foreach (JObject obj in JArray.Load(reader).Children()) + { + string uniqueID = obj.Value(nameof(IManifestDependency.UniqueID)); + string minVersion = obj.Value(nameof(IManifestDependency.MinimumVersion)); + bool required = obj.Value(nameof(IManifestDependency.IsRequired)) ?? true; + result.Add(new ManifestDependency(uniqueID, minVersion, required)); + } + return result.ToArray(); + } + + /// Writes the JSON representation of the object. + /// The JSON writer. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new InvalidOperationException("This converter does not write JSON."); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs new file mode 100644 index 00000000..3232dde4 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// Handles deserialisation of arrays. + internal class ModCompatibilityArrayConverter : JsonConverter + { + /********* + ** Accessors + *********/ + /// Whether this converter can write JSON. + public override bool CanWrite => false; + + + /********* + ** Public methods + *********/ + /// Get whether this instance can convert the specified object type. + /// The object type. + public override bool CanConvert(Type objectType) + { + return objectType == typeof(ModCompatibility[]); + } + + + /********* + ** Protected methods + *********/ + /// Read the JSON representation of the object. + /// The JSON reader. + /// The object type. + /// The object being read. + /// The calling serializer. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List result = new List(); + foreach (JProperty property in JObject.Load(reader).Properties()) + { + string range = property.Name; + ModStatus status = (ModStatus)Enum.Parse(typeof(ModStatus), property.Value.Value(nameof(ModCompatibility.Status))); + string reasonPhrase = property.Value.Value(nameof(ModCompatibility.ReasonPhrase)); + + result.Add(new ModCompatibility(range, status, reasonPhrase)); + } + return result.ToArray(); + } + + /// Writes the JSON representation of the object. + /// The JSON writer. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new InvalidOperationException("This converter does not write JSON."); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs new file mode 100644 index 00000000..8a10db47 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs @@ -0,0 +1,19 @@ +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// Handles deserialisation of . + internal class ModDataIdConverter : SimpleReadOnlyConverter + { + /********* + ** Protected methods + *********/ + /// Read a JSON string. + /// The JSON string value. + /// The path to the current JSON node. + protected override ModDataID ReadString(string str, string path) + { + return new ModDataID(str); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs new file mode 100644 index 00000000..50181809 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Exceptions; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// Handles deserialisation of . + internal class SemanticVersionConverter : SimpleReadOnlyConverter + { + /********* + ** Protected methods + *********/ + /// Read a JSON object. + /// The JSON object to read. + /// The path to the current JSON node. + protected override ISemanticVersion ReadObject(JObject obj, string path) + { + int major = obj.Value(nameof(ISemanticVersion.MajorVersion)); + int minor = obj.Value(nameof(ISemanticVersion.MinorVersion)); + int patch = obj.Value(nameof(ISemanticVersion.PatchVersion)); + string build = obj.Value(nameof(ISemanticVersion.Build)); + return new LegacyManifestVersion(major, minor, patch, build); + } + + /// Read a JSON string. + /// The JSON string value. + /// The path to the current JSON node. + protected override ISemanticVersion ReadString(string str, string path) + { + if (string.IsNullOrWhiteSpace(str)) + return null; + if (!SemanticVersion.TryParse(str, out ISemanticVersion version)) + throw new SParseException($"Can't parse semantic version from invalid value '{str}', should be formatted like 1.2, 1.2.30, or 1.2.30-beta (path: {path})."); + return version; + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/Converters/StringEnumConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/StringEnumConverter.cs similarity index 91% rename from src/SMAPI/Framework/Serialisation/Converters/StringEnumConverter.cs rename to src/SMAPI/Framework/Serialisation/SmapiConverters/StringEnumConverter.cs index 0a612c74..c88ac834 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/StringEnumConverter.cs +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/StringEnumConverter.cs @@ -1,7 +1,7 @@ using System; using Newtonsoft.Json.Converters; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters { /// A variant of which only converts a specified enum. /// The enum type. diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index f5060e2d..ca05399d 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -110,10 +110,14 @@ + + + + - - - + + + @@ -181,8 +185,7 @@ - - +