From 625c538f244519700f3942b2b2969845db9a99b0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 5 Jun 2018 20:22:46 -0400 Subject: move manifest parsing into toolkit (#532) --- .../Converters/SemanticVersionConverter.cs | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs (limited to 'src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs') diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs new file mode 100644 index 00000000..2075d27e --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Toolkit.Serialisation.Models; + +namespace StardewModdingAPI.Toolkit.Serialisation.Converters +{ + /// 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 SemanticVersion ReadObject(JObject obj, string path) + { + int major = obj.ValueIgnoreCase("MajorVersion"); + int minor = obj.ValueIgnoreCase("MinorVersion"); + int patch = obj.ValueIgnoreCase("PatchVersion"); + string build = obj.ValueIgnoreCase("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 SemanticVersion 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 (SemanticVersion)version; + } + } +} -- cgit From 6eba10948bf39d5e05505ec060f6920f84610d58 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 5 Jun 2018 23:03:26 -0400 Subject: fix version parsing issues in new toolkit code (#532) --- src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 17 --------- .../Framework/Models/ManifestContentPackFor.cs | 2 +- .../Serialisation/SemanticVersionConverter.cs | 40 ++++++++++++++++++++++ src/SMAPI/Program.cs | 3 +- src/SMAPI/StardewModdingAPI.csproj | 1 + .../Converters/SemanticVersionConverter.cs | 5 ++- .../Serialisation/Models/LegacyManifestVersion.cs | 26 -------------- 7 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs delete mode 100644 src/StardewModdingAPI.Toolkit/Serialisation/Models/LegacyManifestVersion.cs (limited to 'src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs') diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index b797393b..feab452a 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; using NUnit.Framework; using StardewModdingAPI.Framework; -using StardewModdingAPI.Toolkit.Serialisation.Models; namespace StardewModdingAPI.Tests.Utilities { @@ -272,22 +271,6 @@ namespace StardewModdingAPI.Tests.Utilities Assert.IsTrue(version.IsOlderThan(new SemanticVersion("1.2.30")), "The game version should be considered older than the later semantic versions."); } - /**** - ** LegacyManifestVersion - ****/ - [Test(Description = "Assert that the LegacyManifestVersion subclass correctly parses legacy manifest versions.")] - [TestCase(1, 0, 0, null, ExpectedResult = "1.0")] - [TestCase(3000, 4000, 5000, null, ExpectedResult = "3000.4000.5000")] - [TestCase(1, 2, 3, "", ExpectedResult = "1.2.3")] - [TestCase(1, 2, 3, " ", ExpectedResult = "1.2.3")] - [TestCase(1, 2, 3, "0", ExpectedResult = "1.2.3")] // special case: drop '0' tag for legacy manifest versions - [TestCase(1, 2, 3, "some-tag.4", ExpectedResult = "1.2.3-some-tag.4")] - [TestCase(1, 2, 3, "some-tag.4 ", ExpectedResult = "1.2.3-some-tag.4")] - public string LegacyManifestVersion(int major, int minor, int patch, string tag) - { - return new LegacyManifestVersion(major, minor, patch, tag).ToString(); - } - /********* ** Private methods diff --git a/src/SMAPI/Framework/Models/ManifestContentPackFor.cs b/src/SMAPI/Framework/Models/ManifestContentPackFor.cs index cdad8893..90e20c6a 100644 --- a/src/SMAPI/Framework/Models/ManifestContentPackFor.cs +++ b/src/SMAPI/Framework/Models/ManifestContentPackFor.cs @@ -21,7 +21,7 @@ namespace StardewModdingAPI.Framework.Models public ManifestContentPackFor(Toolkit.Serialisation.Models.ManifestContentPackFor contentPackFor) { this.UniqueID = contentPackFor.UniqueID; - this.MinimumVersion = new SemanticVersion(contentPackFor.MinimumVersion); + this.MinimumVersion = contentPackFor.MinimumVersion != null ? new SemanticVersion(contentPackFor.MinimumVersion) : null; } /// Construct an instance. diff --git a/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs b/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs new file mode 100644 index 00000000..3e05a440 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Toolkit.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation.Converters; + +namespace StardewModdingAPI.Framework.Serialisation +{ + /// 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.ValueIgnoreCase("MajorVersion"); + int minor = obj.ValueIgnoreCase("MinorVersion"); + int patch = obj.ValueIgnoreCase("PatchVersion"); + string build = obj.ValueIgnoreCase("Build"); + if (build == "0") + build = null; // '0' from incorrect examples in old SMAPI documentation + + return new SemanticVersion(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/Program.cs b/src/SMAPI/Program.cs index 05a3134e..cc59c0cd 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -159,7 +159,8 @@ namespace StardewModdingAPI new StringEnumConverter(), new ColorConverter(), new PointConverter(), - new RectangleConverter() + new RectangleConverter(), + new Framework.Serialisation.SemanticVersionConverter() }; foreach (JsonConverter converter in converters) this.JsonHelper.JsonSettings.Converters.Add(converter); diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 3c953ec5..7eb5f95a 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -121,6 +121,7 @@ + diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs index 2075d27e..2ddaa1bf 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs @@ -18,7 +18,10 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Converters int minor = obj.ValueIgnoreCase("MinorVersion"); int patch = obj.ValueIgnoreCase("PatchVersion"); string build = obj.ValueIgnoreCase("Build"); - return new LegacyManifestVersion(major, minor, patch, build); + if (build == "0") + build = null; // '0' from incorrect examples in old SMAPI documentation + + return new SemanticVersion(major, minor, patch, build); } /// Read a JSON string. diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/LegacyManifestVersion.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/LegacyManifestVersion.cs deleted file mode 100644 index 12f6755b..00000000 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/LegacyManifestVersion.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; - -namespace StardewModdingAPI.Toolkit.Serialisation.Models -{ - /// An implementation of that hamdles the legacy version format. - public class LegacyManifestVersion : SemanticVersion - { - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The major version incremented for major API changes. - /// The minor version incremented for backwards-compatible changes. - /// The patch version for backwards-compatible bug fixes. - /// An optional build tag. - [JsonConstructor] - public LegacyManifestVersion(int majorVersion, int minorVersion, int patchVersion, string build = null) - : base( - majorVersion, - minorVersion, - patchVersion, - build != "0" ? build : null // '0' from incorrect examples in old SMAPI documentation - ) - { } - } -} -- cgit From b08e27d13a1f0c82656df95212fc40588b3b5314 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 21:51:51 -0400 Subject: merge IManifest interfaces into new project (#532) --- src/SMAPI.Tests/Core/ModResolverTests.cs | 25 +++--- src/SMAPI/Framework/ModHelpers/ModHelper.cs | 4 +- src/SMAPI/Framework/ModLoading/ModResolver.cs | 9 +- src/SMAPI/Framework/Models/Manifest.cs | 97 ---------------------- .../Framework/Models/ManifestContentPackFor.cs | 36 -------- src/SMAPI/Framework/Models/ManifestDependency.cs | 40 --------- .../Serialisation/SemanticVersionConverter.cs | 40 --------- src/SMAPI/IManifest.cs | 44 ---------- src/SMAPI/IManifestContentPackFor.cs | 12 --- src/SMAPI/IManifestDependency.cs | 18 ---- src/SMAPI/Metadata/InstructionMetadata.cs | 7 +- src/SMAPI/Program.cs | 3 +- src/SMAPI/StardewModdingAPI.csproj | 7 -- .../IManifest.cs | 44 ++++++++++ .../IManifestContentPackFor.cs | 12 +++ .../IManifestDependency.cs | 18 ++++ .../Converters/SemanticVersionConverter.cs | 1 - .../Serialisation/Models/Manifest.cs | 37 +++++++-- .../Serialisation/Models/ManifestContentPackFor.cs | 8 +- .../Serialisation/Models/ManifestDependency.cs | 8 +- 20 files changed, 142 insertions(+), 328 deletions(-) delete mode 100644 src/SMAPI/Framework/Models/Manifest.cs delete mode 100644 src/SMAPI/Framework/Models/ManifestContentPackFor.cs delete mode 100644 src/SMAPI/Framework/Models/ManifestDependency.cs delete mode 100644 src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs delete mode 100644 src/SMAPI/IManifest.cs delete mode 100644 src/SMAPI/IManifestContentPackFor.cs delete mode 100644 src/SMAPI/IManifestDependency.cs create mode 100644 src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifest.cs create mode 100644 src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestContentPackFor.cs create mode 100644 src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestDependency.cs (limited to 'src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs') diff --git a/src/SMAPI.Tests/Core/ModResolverTests.cs b/src/SMAPI.Tests/Core/ModResolverTests.cs index 2fbeb9b6..a0fe2023 100644 --- a/src/SMAPI.Tests/Core/ModResolverTests.cs +++ b/src/SMAPI.Tests/Core/ModResolverTests.cs @@ -7,9 +7,9 @@ using Newtonsoft.Json; using NUnit.Framework; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.ModData; -using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Toolkit.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation.Models; namespace StardewModdingAPI.Tests.Core { @@ -472,17 +472,18 @@ namespace StardewModdingAPI.Tests.Core /// The value. private Manifest GetManifest(string id = null, string name = null, string version = null, string entryDll = null, string contentPackForID = null, string minimumApiVersion = null, IManifestDependency[] dependencies = null) { - return new Manifest( - uniqueID: id ?? $"{Sample.String()}.{Sample.String()}", - name: name ?? id ?? Sample.String(), - author: Sample.String(), - description: Sample.String(), - version: version != null ? new SemanticVersion(version) : new SemanticVersion(Sample.Int(), Sample.Int(), Sample.Int(), Sample.String()), - entryDll: entryDll ?? $"{Sample.String()}.dll", - contentPackFor: contentPackForID != null ? new ManifestContentPackFor(contentPackForID) : null, - minimumApiVersion: minimumApiVersion != null ? new SemanticVersion(minimumApiVersion) : null, - dependencies: dependencies - ); + return new Manifest + { + UniqueID = id ?? $"{Sample.String()}.{Sample.String()}", + Name = name ?? id ?? Sample.String(), + Author = Sample.String(), + Description = Sample.String(), + Version = version != null ? new SemanticVersion(version) : new SemanticVersion(Sample.Int(), Sample.Int(), Sample.Int(), Sample.String()), + EntryDll = entryDll ?? $"{Sample.String()}.dll", + ContentPackFor = contentPackForID != null ? new ManifestContentPackFor { UniqueID = contentPackForID } : null, + MinimumApiVersion = minimumApiVersion != null ? new SemanticVersion(minimumApiVersion) : null, + Dependencies = dependencies + }; } /// Get a randomised basic manifest. diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index 18904857..d9498e83 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -4,8 +4,8 @@ using System.IO; using System.Linq; using StardewModdingAPI.Events; using StardewModdingAPI.Framework.Input; -using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Toolkit.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation.Models; using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.Framework.ModHelpers @@ -185,7 +185,7 @@ namespace StardewModdingAPI.Framework.ModHelpers author: author, description: description, version: version, - contentPackFor: new ManifestContentPackFor(this.ModID) + contentPackFor: this.ModID ); // create content pack diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index 3366e8c1..fde921e6 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -4,10 +4,9 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using StardewModdingAPI.Framework.ModData; -using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Toolkit.Serialisation; +using StardewModdingAPI.Toolkit.Serialisation.Models; using StardewModdingAPI.Toolkit.Utilities; -using ToolkitManifest = StardewModdingAPI.Toolkit.Serialisation.Models.Manifest; namespace StardewModdingAPI.Framework.ModLoading { @@ -33,15 +32,13 @@ namespace StardewModdingAPI.Framework.ModLoading string path = Path.Combine(modDir.FullName, "manifest.json"); try { - ToolkitManifest rawManifest = jsonHelper.ReadJsonFile(path); - if (rawManifest == null) + manifest = jsonHelper.ReadJsonFile(path); + if (manifest == null) { error = File.Exists(path) ? "its manifest is invalid." : "it doesn't have a manifest."; } - else - manifest = new Manifest(rawManifest); } catch (SParseException ex) { diff --git a/src/SMAPI/Framework/Models/Manifest.cs b/src/SMAPI/Framework/Models/Manifest.cs deleted file mode 100644 index 92ffe0dc..00000000 --- a/src/SMAPI/Framework/Models/Manifest.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -namespace StardewModdingAPI.Framework.Models -{ - /// A manifest which describes a mod for SMAPI. - internal class Manifest : IManifest - { - /********* - ** Accessors - *********/ - /// The mod name. - public string Name { get; } - - /// A brief description of the mod. - public string Description { get; } - - /// The mod author's name. - public string Author { get; } - - /// The mod version. - public ISemanticVersion Version { get; } - - /// The minimum SMAPI version required by this mod, if any. - public ISemanticVersion MinimumApiVersion { get; } - - /// The name of the DLL in the directory that has the method. Mutually exclusive with . - public string EntryDll { get; } - - /// The mod which will read this as a content pack. Mutually exclusive with . - public IManifestContentPackFor ContentPackFor { get; } - - /// The other mods that must be loaded before this mod. - public IManifestDependency[] Dependencies { get; } - - /// The namespaced mod IDs to query for updates (like Nexus:541). - public string[] UpdateKeys { get; set; } - - /// The unique mod ID. - public string UniqueID { get; } - - /// Any manifest fields which didn't match a valid field. - [JsonExtensionData] - public IDictionary ExtraFields { get; } - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The toolkit manifest. - public Manifest(Toolkit.Serialisation.Models.Manifest manifest) - : this( - uniqueID: manifest.UniqueID, - name: manifest.Name, - author: manifest.Author, - description: manifest.Description, - version: manifest.Version != null ? new SemanticVersion(manifest.Version) : null, - entryDll: manifest.EntryDll, - minimumApiVersion: manifest.MinimumApiVersion != null ? new SemanticVersion(manifest.MinimumApiVersion) : null, - contentPackFor: manifest.ContentPackFor != null ? new ManifestContentPackFor(manifest.ContentPackFor) : null, - dependencies: manifest.Dependencies?.Select(p => p != null ? (IManifestDependency)new ManifestDependency(p) : null).ToArray(), - updateKeys: manifest.UpdateKeys, - extraFields: manifest.ExtraFields - ) - { } - - /// Construct an instance for a transitional content pack. - /// The unique mod ID. - /// The mod name. - /// The mod author's name. - /// A brief description of the mod. - /// The mod version. - /// The name of the DLL in the directory that has the method. Mutually exclusive with . - /// The minimum SMAPI version required by this mod, if any. - /// The modID which will read this as a content pack. Mutually exclusive with . - /// The other mods that must be loaded before this mod. - /// The namespaced mod IDs to query for updates (like Nexus:541). - /// Any manifest fields which didn't match a valid field. - public Manifest(string uniqueID, string name, string author, string description, ISemanticVersion version, string entryDll = null, ISemanticVersion minimumApiVersion = null, IManifestContentPackFor contentPackFor = null, IManifestDependency[] dependencies = null, string[] updateKeys = null, IDictionary extraFields = null) - { - this.Name = name; - this.Author = author; - this.Description = description; - this.Version = version; - this.UniqueID = uniqueID; - this.UpdateKeys = new string[0]; - this.EntryDll = entryDll; - this.ContentPackFor = contentPackFor; - this.MinimumApiVersion = minimumApiVersion; - this.Dependencies = dependencies ?? new IManifestDependency[0]; - this.UpdateKeys = updateKeys ?? new string[0]; - this.ExtraFields = extraFields; - } - } -} diff --git a/src/SMAPI/Framework/Models/ManifestContentPackFor.cs b/src/SMAPI/Framework/Models/ManifestContentPackFor.cs deleted file mode 100644 index 90e20c6a..00000000 --- a/src/SMAPI/Framework/Models/ManifestContentPackFor.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace StardewModdingAPI.Framework.Models -{ - /// Indicates which mod can read the content pack represented by the containing manifest. - internal class ManifestContentPackFor : IManifestContentPackFor - { - /********* - ** Accessors - *********/ - /// The unique ID of the mod which can read this content pack. - public string UniqueID { get; } - - /// The minimum required version (if any). - public ISemanticVersion MinimumVersion { get; } - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The toolkit instance. - public ManifestContentPackFor(Toolkit.Serialisation.Models.ManifestContentPackFor contentPackFor) - { - this.UniqueID = contentPackFor.UniqueID; - this.MinimumVersion = contentPackFor.MinimumVersion != null ? new SemanticVersion(contentPackFor.MinimumVersion) : null; - } - - /// Construct an instance. - /// The unique ID of the mod which can read this content pack. - /// The minimum required version (if any). - public ManifestContentPackFor(string uniqueID, ISemanticVersion minimumVersion = null) - { - this.UniqueID = uniqueID; - this.MinimumVersion = minimumVersion; - } - } -} diff --git a/src/SMAPI/Framework/Models/ManifestDependency.cs b/src/SMAPI/Framework/Models/ManifestDependency.cs deleted file mode 100644 index e92597f3..00000000 --- a/src/SMAPI/Framework/Models/ManifestDependency.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace StardewModdingAPI.Framework.Models -{ - /// A mod dependency listed in a mod manifest. - internal class ManifestDependency : IManifestDependency - { - /********* - ** Accessors - *********/ - /// The unique mod ID to require. - public string UniqueID { get; } - - /// The minimum required version (if any). - public ISemanticVersion MinimumVersion { get; } - - /// Whether the dependency must be installed to use the mod. - public bool IsRequired { get; } - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The toolkit instance. - public ManifestDependency(Toolkit.Serialisation.Models.ManifestDependency dependency) - : this(dependency.UniqueID, dependency.MinimumVersion?.ToString(), dependency.IsRequired) { } - - /// Construct an instance. - /// The unique mod ID to require. - /// The minimum required version (if any). - /// Whether the dependency must be installed to use the mod. - public ManifestDependency(string uniqueID, string minimumVersion, bool required = true) - { - this.UniqueID = uniqueID; - this.MinimumVersion = !string.IsNullOrWhiteSpace(minimumVersion) - ? new SemanticVersion(minimumVersion) - : null; - this.IsRequired = required; - } - } -} diff --git a/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs b/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs deleted file mode 100644 index 3e05a440..00000000 --- a/src/SMAPI/Framework/Serialisation/SemanticVersionConverter.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Newtonsoft.Json.Linq; -using StardewModdingAPI.Toolkit.Serialisation; -using StardewModdingAPI.Toolkit.Serialisation.Converters; - -namespace StardewModdingAPI.Framework.Serialisation -{ - /// 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.ValueIgnoreCase("MajorVersion"); - int minor = obj.ValueIgnoreCase("MinorVersion"); - int patch = obj.ValueIgnoreCase("PatchVersion"); - string build = obj.ValueIgnoreCase("Build"); - if (build == "0") - build = null; // '0' from incorrect examples in old SMAPI documentation - - return new SemanticVersion(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/IManifest.cs b/src/SMAPI/IManifest.cs deleted file mode 100644 index 6c07d374..00000000 --- a/src/SMAPI/IManifest.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; - -namespace StardewModdingAPI -{ - /// A manifest which describes a mod for SMAPI. - public interface IManifest - { - /********* - ** Accessors - *********/ - /// The mod name. - string Name { get; } - - /// A brief description of the mod. - string Description { get; } - - /// The mod author's name. - string Author { get; } - - /// The mod version. - ISemanticVersion Version { get; } - - /// The minimum SMAPI version required by this mod, if any. - ISemanticVersion MinimumApiVersion { get; } - - /// The unique mod ID. - string UniqueID { get; } - - /// The name of the DLL in the directory that has the method. Mutually exclusive with . - string EntryDll { get; } - - /// The mod which will read this as a content pack. Mutually exclusive with . - IManifestContentPackFor ContentPackFor { get; } - - /// The other mods that must be loaded before this mod. - IManifestDependency[] Dependencies { get; } - - /// The namespaced mod IDs to query for updates (like Nexus:541). - string[] UpdateKeys { get; } - - /// Any manifest fields which didn't match a valid field. - IDictionary ExtraFields { get; } - } -} diff --git a/src/SMAPI/IManifestContentPackFor.cs b/src/SMAPI/IManifestContentPackFor.cs deleted file mode 100644 index f05a3873..00000000 --- a/src/SMAPI/IManifestContentPackFor.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace StardewModdingAPI -{ - /// Indicates which mod can read the content pack represented by the containing manifest. - public interface IManifestContentPackFor - { - /// The unique ID of the mod which can read this content pack. - string UniqueID { get; } - - /// The minimum required version (if any). - ISemanticVersion MinimumVersion { get; } - } -} diff --git a/src/SMAPI/IManifestDependency.cs b/src/SMAPI/IManifestDependency.cs deleted file mode 100644 index e86cd1f4..00000000 --- a/src/SMAPI/IManifestDependency.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace StardewModdingAPI -{ - /// A mod dependency listed in a mod manifest. - public interface IManifestDependency - { - /********* - ** Accessors - *********/ - /// The unique mod ID to require. - string UniqueID { get; } - - /// The minimum required version (if any). - ISemanticVersion MinimumVersion { get; } - - /// Whether the dependency must be installed to use the mod. - bool IsRequired { get; } - } -} diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 543d44a7..c5128eb1 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -37,8 +37,11 @@ namespace StardewModdingAPI.Metadata // rewrite for SMAPI 2.0 new VirtualEntryCallRemover(), - // rewrite for SMAPI 2.6 - new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), type => type.Scope.Name == "StardewModdingAPI"), // moved to SMAPI.Toolkit.CoreInterfaces + // rewrite for SMAPI 2.6 (types moved into SMAPI.Toolkit.CoreInterfaces) + new TypeReferenceRewriter("StardewModdingAPI.IManifest", typeof(IManifest), type => type.Scope.Name == "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.IManifestContentPackFor", typeof(IManifestContentPackFor), type => type.Scope.Name == "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.IManifestDependency", typeof(IManifestDependency), type => type.Scope.Name == "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), type => type.Scope.Name == "StardewModdingAPI"), // rewrite for Stardew Valley 1.3 new StaticFieldToConstantRewriter(typeof(Game1), "tileSize", Game1.tileSize), diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index a51d6380..1b276988 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -201,8 +201,7 @@ namespace StardewModdingAPI new StringEnumConverter(), new ColorConverter(), new PointConverter(), - new RectangleConverter(), - new Framework.Serialisation.SemanticVersionConverter() + new RectangleConverter() }; foreach (JsonConverter converter in converters) this.JsonHelper.JsonSettings.Converters.Add(converter); diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index c872391c..4852f70c 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -126,11 +126,7 @@ - - - - @@ -186,7 +182,6 @@ - @@ -258,7 +253,6 @@ - @@ -275,7 +269,6 @@ - diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifest.cs b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifest.cs new file mode 100644 index 00000000..6c07d374 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifest.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; + +namespace StardewModdingAPI +{ + /// A manifest which describes a mod for SMAPI. + public interface IManifest + { + /********* + ** Accessors + *********/ + /// The mod name. + string Name { get; } + + /// A brief description of the mod. + string Description { get; } + + /// The mod author's name. + string Author { get; } + + /// The mod version. + ISemanticVersion Version { get; } + + /// The minimum SMAPI version required by this mod, if any. + ISemanticVersion MinimumApiVersion { get; } + + /// The unique mod ID. + string UniqueID { get; } + + /// The name of the DLL in the directory that has the method. Mutually exclusive with . + string EntryDll { get; } + + /// The mod which will read this as a content pack. Mutually exclusive with . + IManifestContentPackFor ContentPackFor { get; } + + /// The other mods that must be loaded before this mod. + IManifestDependency[] Dependencies { get; } + + /// The namespaced mod IDs to query for updates (like Nexus:541). + string[] UpdateKeys { get; } + + /// Any manifest fields which didn't match a valid field. + IDictionary ExtraFields { get; } + } +} diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestContentPackFor.cs b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestContentPackFor.cs new file mode 100644 index 00000000..f05a3873 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestContentPackFor.cs @@ -0,0 +1,12 @@ +namespace StardewModdingAPI +{ + /// Indicates which mod can read the content pack represented by the containing manifest. + public interface IManifestContentPackFor + { + /// The unique ID of the mod which can read this content pack. + string UniqueID { get; } + + /// The minimum required version (if any). + ISemanticVersion MinimumVersion { get; } + } +} diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestDependency.cs b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestDependency.cs new file mode 100644 index 00000000..e86cd1f4 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/IManifestDependency.cs @@ -0,0 +1,18 @@ +namespace StardewModdingAPI +{ + /// A mod dependency listed in a mod manifest. + public interface IManifestDependency + { + /********* + ** Accessors + *********/ + /// The unique mod ID to require. + string UniqueID { get; } + + /// The minimum required version (if any). + ISemanticVersion MinimumVersion { get; } + + /// Whether the dependency must be installed to use the mod. + bool IsRequired { get; } + } +} diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs index 2ddaa1bf..eff95d1f 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs @@ -1,5 +1,4 @@ using Newtonsoft.Json.Linq; -using StardewModdingAPI.Toolkit.Serialisation.Models; namespace StardewModdingAPI.Toolkit.Serialisation.Converters { diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs index 68987dd1..6ec57258 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs @@ -5,7 +5,7 @@ using StardewModdingAPI.Toolkit.Serialisation.Converters; namespace StardewModdingAPI.Toolkit.Serialisation.Models { /// A manifest which describes a mod for SMAPI. - public class Manifest + public class Manifest : IManifest { /********* ** Accessors @@ -20,21 +20,23 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string Author { get; set; } /// The mod version. - public SemanticVersion Version { get; set; } + [JsonConverter(typeof(SemanticVersionConverter))] + public ISemanticVersion Version { get; set; } /// The minimum SMAPI version required by this mod, if any. - public SemanticVersion MinimumApiVersion { get; set; } + [JsonConverter(typeof(SemanticVersionConverter))] + public ISemanticVersion MinimumApiVersion { get; set; } /// The name of the DLL in the directory that has the Entry method. Mutually exclusive with . public string EntryDll { get; set; } /// The mod which will read this as a content pack. Mutually exclusive with . [JsonConverter(typeof(ManifestContentPackForConverter))] - public ManifestContentPackFor ContentPackFor { get; set; } + public IManifestContentPackFor ContentPackFor { get; set; } /// The other mods that must be loaded before this mod. [JsonConverter(typeof(ManifestDependencyArrayConverter))] - public ManifestDependency[] Dependencies { get; set; } + public IManifestDependency[] Dependencies { get; set; } /// The namespaced mod IDs to query for updates (like Nexus:541). public string[] UpdateKeys { get; set; } @@ -45,5 +47,30 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models /// Any manifest fields which didn't match a valid field. [JsonExtensionData] public IDictionary ExtraFields { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public Manifest() { } + + /// Construct an instance for a transitional content pack. + /// The unique mod ID. + /// The mod name. + /// The mod author's name. + /// A brief description of the mod. + /// The mod version. + /// The modID which will read this as a content pack. + public Manifest(string uniqueID, string name, string author, string description, ISemanticVersion version, string contentPackFor = null) + { + this.Name = name; + this.Author = author; + this.Description = description; + this.Version = version; + this.UniqueID = uniqueID; + this.UpdateKeys = new string[0]; + this.ContentPackFor = new ManifestContentPackFor { UniqueID = contentPackFor }; + } } } diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs index 00546533..64808dcf 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs @@ -1,7 +1,10 @@ +using Newtonsoft.Json; +using StardewModdingAPI.Toolkit.Serialisation.Converters; + namespace StardewModdingAPI.Toolkit.Serialisation.Models { /// Indicates which mod can read the content pack represented by the containing manifest. - public class ManifestContentPackFor + public class ManifestContentPackFor : IManifestContentPackFor { /********* ** Accessors @@ -10,6 +13,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string UniqueID { get; set; } /// The minimum required version (if any). - public SemanticVersion MinimumVersion { get; set; } + [JsonConverter(typeof(SemanticVersionConverter))] + public ISemanticVersion MinimumVersion { get; set; } } } diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs index d902f9ac..67e733dd 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs @@ -1,7 +1,10 @@ +using Newtonsoft.Json; +using StardewModdingAPI.Toolkit.Serialisation.Converters; + namespace StardewModdingAPI.Toolkit.Serialisation.Models { /// A mod dependency listed in a mod manifest. - public class ManifestDependency + public class ManifestDependency : IManifestDependency { /********* ** Accessors @@ -10,7 +13,8 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string UniqueID { get; set; } /// The minimum required version (if any). - public SemanticVersion MinimumVersion { get; set; } + [JsonConverter(typeof(SemanticVersionConverter))] + public ISemanticVersion MinimumVersion { get; set; } /// Whether the dependency must be installed to use the mod. public bool IsRequired { get; set; } -- cgit From 85efb3112912a28dbdc82b18d0be8dd117f8c8ee Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 23:01:39 -0400 Subject: fix ISemanticVersion deserialisation errors (#532) --- .../Serialisation/Converters/SemanticVersionConverter.cs | 8 ++++---- src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs | 2 -- .../Serialisation/Models/ManifestContentPackFor.cs | 4 ---- .../Serialisation/Models/ManifestDependency.cs | 4 ---- 4 files changed, 4 insertions(+), 14 deletions(-) (limited to 'src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs') diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs index eff95d1f..4f0949fa 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs @@ -2,8 +2,8 @@ using Newtonsoft.Json.Linq; namespace StardewModdingAPI.Toolkit.Serialisation.Converters { - /// Handles deserialisation of . - internal class SemanticVersionConverter : SimpleReadOnlyConverter + /// Handles deserialisation of . + internal class SemanticVersionConverter : SimpleReadOnlyConverter { /********* ** Protected methods @@ -11,7 +11,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Converters /// Read a JSON object. /// The JSON object to read. /// The path to the current JSON node. - protected override SemanticVersion ReadObject(JObject obj, string path) + protected override ISemanticVersion ReadObject(JObject obj, string path) { int major = obj.ValueIgnoreCase("MajorVersion"); int minor = obj.ValueIgnoreCase("MinorVersion"); @@ -26,7 +26,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Converters /// Read a JSON string. /// The JSON string value. /// The path to the current JSON node. - protected override SemanticVersion ReadString(string str, string path) + protected override ISemanticVersion ReadString(string str, string path) { if (string.IsNullOrWhiteSpace(str)) return null; diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs index 6ec57258..6cb9496b 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/Manifest.cs @@ -20,11 +20,9 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string Author { get; set; } /// The mod version. - [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion Version { get; set; } /// The minimum SMAPI version required by this mod, if any. - [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion MinimumApiVersion { get; set; } /// The name of the DLL in the directory that has the Entry method. Mutually exclusive with . diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs index 64808dcf..d0e42216 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs @@ -1,6 +1,3 @@ -using Newtonsoft.Json; -using StardewModdingAPI.Toolkit.Serialisation.Converters; - namespace StardewModdingAPI.Toolkit.Serialisation.Models { /// Indicates which mod can read the content pack represented by the containing manifest. @@ -13,7 +10,6 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string UniqueID { get; set; } /// The minimum required version (if any). - [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion MinimumVersion { get; set; } } } diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs index 67e733dd..8db58d5d 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Models/ManifestDependency.cs @@ -1,6 +1,3 @@ -using Newtonsoft.Json; -using StardewModdingAPI.Toolkit.Serialisation.Converters; - namespace StardewModdingAPI.Toolkit.Serialisation.Models { /// A mod dependency listed in a mod manifest. @@ -13,7 +10,6 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models public string UniqueID { get; set; } /// The minimum required version (if any). - [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion MinimumVersion { get; set; } /// Whether the dependency must be installed to use the mod. -- cgit From 89ad599561a058289d8ea44e0c345f1a30a3a6ac Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 28 Jun 2018 21:41:00 -0400 Subject: add support for writing versions to JSON --- docs/release-notes.md | 1 + src/SMAPI.Web/Startup.cs | 4 ++ .../Converters/SemanticVersionConverter.cs | 60 ++++++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) (limited to 'src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 062f902e..a8f6d851 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -44,6 +44,7 @@ * Added Harmony DLL for internal use by SMAPI. (Mods should still include their own copy for backwards compatibility, and in case it's removed later. SMAPI will always load its own version though.) * Added option to suppress update checks for a specific mod in `StardewModdingAPI.config.json`. * Added absolute pixels to `ICursorPosition`. + * Added support for reading/writing `ISemanticVersion` to JSON. * Update checks now use the update key order when deciding which to link to. * Fixed error if a mod loads a PNG while the game is loading (e.g. custom map tilesheets via `IAssetLoader`). * Fixed assets loaded by temporary content managers not being editable by mods. diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs index 58584348..ced6e1c7 100644 --- a/src/SMAPI.Web/Startup.cs +++ b/src/SMAPI.Web/Startup.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using StardewModdingAPI.Toolkit.Serialisation; using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Framework.Clients.Chucklefish; using StardewModdingAPI.Web.Framework.Clients.GitHub; @@ -56,6 +57,9 @@ namespace StardewModdingAPI.Web .ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider())) .AddJsonOptions(options => { + foreach (JsonConverter converter in new JsonHelper().JsonSettings.Converters) + options.SerializerSettings.Converters.Add(converter); + options.SerializerSettings.Formatting = Formatting.Indented; options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); diff --git a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs index 4f0949fa..9b2f5e7d 100644 --- a/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs +++ b/src/StardewModdingAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs @@ -1,17 +1,67 @@ +using System; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace StardewModdingAPI.Toolkit.Serialisation.Converters { /// Handles deserialisation of . - internal class SemanticVersionConverter : SimpleReadOnlyConverter + internal class SemanticVersionConverter : JsonConverter { /********* - ** Protected methods + ** Accessors + *********/ + /// Get whether this converter can read JSON. + public override bool CanRead => true; + + /// Get whether this converter can write JSON. + public override bool CanWrite => true; + + + /********* + ** Public methods + *********/ + /// Get whether this instance can convert the specified object type. + /// The object type. + public override bool CanConvert(Type objectType) + { + return typeof(ISemanticVersion).IsAssignableFrom(objectType); + } + + /// 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) + { + string path = reader.Path; + switch (reader.TokenType) + { + case JsonToken.StartObject: + return this.ReadObject(JObject.Load(reader)); + case JsonToken.String: + return this.ReadString(JToken.Load(reader).Value(), path); + default: + throw new SParseException($"Can't parse {nameof(ISemanticVersion)} from {reader.TokenType} node (path: {reader.Path})."); + } + } + + /// 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) + { + writer.WriteValue(value?.ToString()); + } + + + /********* + ** Private 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) + private ISemanticVersion ReadObject(JObject obj) { int major = obj.ValueIgnoreCase("MajorVersion"); int minor = obj.ValueIgnoreCase("MinorVersion"); @@ -26,7 +76,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Converters /// Read a JSON string. /// The JSON string value. /// The path to the current JSON node. - protected override ISemanticVersion ReadString(string str, string path) + private ISemanticVersion ReadString(string str, string path) { if (string.IsNullOrWhiteSpace(str)) return null; -- cgit