summaryrefslogtreecommitdiff
path: root/src/SMAPI.Toolkit/Serialisation
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Toolkit/Serialisation')
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Converters/ManifestContentPackForConverter.cs50
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Converters/ManifestDependencyArrayConverter.cs60
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs86
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Converters/SimpleReadOnlyConverter.cs76
-rw-r--r--src/SMAPI.Toolkit/Serialisation/InternalExtensions.cs21
-rw-r--r--src/SMAPI.Toolkit/Serialisation/JsonHelper.cs136
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Models/Manifest.cs74
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs15
-rw-r--r--src/SMAPI.Toolkit/Serialisation/Models/ManifestDependency.cs35
-rw-r--r--src/SMAPI.Toolkit/Serialisation/SParseException.cs17
10 files changed, 0 insertions, 570 deletions
diff --git a/src/SMAPI.Toolkit/Serialisation/Converters/ManifestContentPackForConverter.cs b/src/SMAPI.Toolkit/Serialisation/Converters/ManifestContentPackForConverter.cs
deleted file mode 100644
index 232c22a7..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Converters/ManifestContentPackForConverter.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using Newtonsoft.Json;
-using StardewModdingAPI.Toolkit.Serialisation.Models;
-
-namespace StardewModdingAPI.Toolkit.Serialisation.Converters
-{
- /// <summary>Handles deserialisation of <see cref="ManifestContentPackFor"/> arrays.</summary>
- public class ManifestContentPackForConverter : JsonConverter
- {
- /*********
- ** Accessors
- *********/
- /// <summary>Whether this converter can write JSON.</summary>
- public override bool CanWrite => false;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Get whether this instance can convert the specified object type.</summary>
- /// <param name="objectType">The object type.</param>
- public override bool CanConvert(Type objectType)
- {
- return objectType == typeof(ManifestContentPackFor[]);
- }
-
-
- /*********
- ** Protected methods
- *********/
- /// <summary>Read the JSON representation of the object.</summary>
- /// <param name="reader">The JSON reader.</param>
- /// <param name="objectType">The object type.</param>
- /// <param name="existingValue">The object being read.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- return serializer.Deserialize<ManifestContentPackFor>(reader);
- }
-
- /// <summary>Writes the JSON representation of the object.</summary>
- /// <param name="writer">The JSON writer.</param>
- /// <param name="value">The value.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- throw new InvalidOperationException("This converter does not write JSON.");
- }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/Converters/ManifestDependencyArrayConverter.cs b/src/SMAPI.Toolkit/Serialisation/Converters/ManifestDependencyArrayConverter.cs
deleted file mode 100644
index 0a304ee3..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Converters/ManifestDependencyArrayConverter.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using StardewModdingAPI.Toolkit.Serialisation.Models;
-
-namespace StardewModdingAPI.Toolkit.Serialisation.Converters
-{
- /// <summary>Handles deserialisation of <see cref="ManifestDependency"/> arrays.</summary>
- internal class ManifestDependencyArrayConverter : JsonConverter
- {
- /*********
- ** Accessors
- *********/
- /// <summary>Whether this converter can write JSON.</summary>
- public override bool CanWrite => false;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Get whether this instance can convert the specified object type.</summary>
- /// <param name="objectType">The object type.</param>
- public override bool CanConvert(Type objectType)
- {
- return objectType == typeof(ManifestDependency[]);
- }
-
-
- /*********
- ** Protected methods
- *********/
- /// <summary>Read the JSON representation of the object.</summary>
- /// <param name="reader">The JSON reader.</param>
- /// <param name="objectType">The object type.</param>
- /// <param name="existingValue">The object being read.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- List<ManifestDependency> result = new List<ManifestDependency>();
- foreach (JObject obj in JArray.Load(reader).Children<JObject>())
- {
- string uniqueID = obj.ValueIgnoreCase<string>(nameof(ManifestDependency.UniqueID));
- string minVersion = obj.ValueIgnoreCase<string>(nameof(ManifestDependency.MinimumVersion));
- bool required = obj.ValueIgnoreCase<bool?>(nameof(ManifestDependency.IsRequired)) ?? true;
- result.Add(new ManifestDependency(uniqueID, minVersion, required));
- }
- return result.ToArray();
- }
-
- /// <summary>Writes the JSON representation of the object.</summary>
- /// <param name="writer">The JSON writer.</param>
- /// <param name="value">The value.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- throw new InvalidOperationException("This converter does not write JSON.");
- }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs b/src/SMAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs
deleted file mode 100644
index c50de4db..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Converters/SemanticVersionConverter.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-namespace StardewModdingAPI.Toolkit.Serialisation.Converters
-{
- /// <summary>Handles deserialisation of <see cref="ISemanticVersion"/>.</summary>
- internal class SemanticVersionConverter : JsonConverter
- {
- /*********
- ** Accessors
- *********/
- /// <summary>Get whether this converter can read JSON.</summary>
- public override bool CanRead => true;
-
- /// <summary>Get whether this converter can write JSON.</summary>
- public override bool CanWrite => true;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Get whether this instance can convert the specified object type.</summary>
- /// <param name="objectType">The object type.</param>
- public override bool CanConvert(Type objectType)
- {
- return typeof(ISemanticVersion).IsAssignableFrom(objectType);
- }
-
- /// <summary>Reads the JSON representation of the object.</summary>
- /// <param name="reader">The JSON reader.</param>
- /// <param name="objectType">The object type.</param>
- /// <param name="existingValue">The object being read.</param>
- /// <param name="serializer">The calling serializer.</param>
- 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<string>(), path);
- default:
- throw new SParseException($"Can't parse {nameof(ISemanticVersion)} from {reader.TokenType} node (path: {reader.Path}).");
- }
- }
-
- /// <summary>Writes the JSON representation of the object.</summary>
- /// <param name="writer">The JSON writer.</param>
- /// <param name="value">The value.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- writer.WriteValue(value?.ToString());
- }
-
-
- /*********
- ** Private methods
- *********/
- /// <summary>Read a JSON object.</summary>
- /// <param name="obj">The JSON object to read.</param>
- private ISemanticVersion ReadObject(JObject obj)
- {
- int major = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.MajorVersion));
- int minor = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.MinorVersion));
- int patch = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.PatchVersion));
- string prereleaseTag = obj.ValueIgnoreCase<string>(nameof(ISemanticVersion.PrereleaseTag));
-
- return new SemanticVersion(major, minor, patch, prereleaseTag);
- }
-
- /// <summary>Read a JSON string.</summary>
- /// <param name="str">The JSON string value.</param>
- /// <param name="path">The path to the current JSON node.</param>
- private 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.Toolkit/Serialisation/Converters/SimpleReadOnlyConverter.cs b/src/SMAPI.Toolkit/Serialisation/Converters/SimpleReadOnlyConverter.cs
deleted file mode 100644
index 5e0b0f4a..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Converters/SimpleReadOnlyConverter.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-namespace StardewModdingAPI.Toolkit.Serialisation.Converters
-{
- /// <summary>The base implementation for simplified converters which deserialise <typeparamref name="T"/> without overriding serialisation.</summary>
- /// <typeparam name="T">The type to deserialise.</typeparam>
- internal abstract class SimpleReadOnlyConverter<T> : JsonConverter
- {
- /*********
- ** Accessors
- *********/
- /// <summary>Whether this converter can write JSON.</summary>
- public override bool CanWrite => false;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Get whether this instance can convert the specified object type.</summary>
- /// <param name="objectType">The object type.</param>
- public override bool CanConvert(Type objectType)
- {
- return objectType == typeof(T);
- }
-
- /// <summary>Writes the JSON representation of the object.</summary>
- /// <param name="writer">The JSON writer.</param>
- /// <param name="value">The value.</param>
- /// <param name="serializer">The calling serializer.</param>
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- throw new InvalidOperationException("This converter does not write JSON.");
- }
-
- /// <summary>Reads the JSON representation of the object.</summary>
- /// <param name="reader">The JSON reader.</param>
- /// <param name="objectType">The object type.</param>
- /// <param name="existingValue">The object being read.</param>
- /// <param name="serializer">The calling serializer.</param>
- 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), path);
- case JsonToken.String:
- return this.ReadString(JToken.Load(reader).Value<string>(), path);
- default:
- throw new SParseException($"Can't parse {typeof(T).Name} from {reader.TokenType} node (path: {reader.Path}).");
- }
- }
-
-
- /*********
- ** Protected methods
- *********/
- /// <summary>Read a JSON object.</summary>
- /// <param name="obj">The JSON object to read.</param>
- /// <param name="path">The path to the current JSON node.</param>
- protected virtual T ReadObject(JObject obj, string path)
- {
- throw new SParseException($"Can't parse {typeof(T).Name} from object node (path: {path}).");
- }
-
- /// <summary>Read a JSON string.</summary>
- /// <param name="str">The JSON string value.</param>
- /// <param name="path">The path to the current JSON node.</param>
- protected virtual T ReadString(string str, string path)
- {
- throw new SParseException($"Can't parse {typeof(T).Name} from string node (path: {path}).");
- }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/InternalExtensions.cs b/src/SMAPI.Toolkit/Serialisation/InternalExtensions.cs
deleted file mode 100644
index 12b2c933..00000000
--- a/src/SMAPI.Toolkit/Serialisation/InternalExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using Newtonsoft.Json.Linq;
-
-namespace StardewModdingAPI.Toolkit.Serialisation
-{
- /// <summary>Provides extension methods for parsing JSON.</summary>
- public static class JsonExtensions
- {
- /// <summary>Get a JSON field value from a case-insensitive field name. This will check for an exact match first, then search without case sensitivity.</summary>
- /// <typeparam name="T">The value type.</typeparam>
- /// <param name="obj">The JSON object to search.</param>
- /// <param name="fieldName">The field name.</param>
- public static T ValueIgnoreCase<T>(this JObject obj, string fieldName)
- {
- JToken token = obj.GetValue(fieldName, StringComparison.InvariantCultureIgnoreCase);
- return token != null
- ? token.Value<T>()
- : default(T);
- }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/JsonHelper.cs b/src/SMAPI.Toolkit/Serialisation/JsonHelper.cs
deleted file mode 100644
index cf2ce0d1..00000000
--- a/src/SMAPI.Toolkit/Serialisation/JsonHelper.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using StardewModdingAPI.Toolkit.Serialisation.Converters;
-
-namespace StardewModdingAPI.Toolkit.Serialisation
-{
- /// <summary>Encapsulates SMAPI's JSON file parsing.</summary>
- public class JsonHelper
- {
- /*********
- ** Accessors
- *********/
- /// <summary>The JSON settings to use when serialising and deserialising files.</summary>
- public JsonSerializerSettings JsonSettings { get; } = new JsonSerializerSettings
- {
- Formatting = Formatting.Indented,
- ObjectCreationHandling = ObjectCreationHandling.Replace, // avoid issue where default ICollection<T> values are duplicated each time the config is loaded
- Converters = new List<JsonConverter>
- {
- new SemanticVersionConverter(),
- new StringEnumConverter()
- }
- };
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Read a JSON file.</summary>
- /// <typeparam name="TModel">The model type.</typeparam>
- /// <param name="fullPath">The absolete file path.</param>
- /// <param name="result">The parsed content model.</param>
- /// <returns>Returns false if the file doesn't exist, else true.</returns>
- /// <exception cref="ArgumentException">The given <paramref name="fullPath"/> is empty or invalid.</exception>
- /// <exception cref="JsonReaderException">The file contains invalid JSON.</exception>
- public bool ReadJsonFileIfExists<TModel>(string fullPath, out TModel result)
- {
- // validate
- if (string.IsNullOrWhiteSpace(fullPath))
- throw new ArgumentException("The file path is empty or invalid.", nameof(fullPath));
-
- // read file
- string json;
- try
- {
- json = File.ReadAllText(fullPath);
- }
- catch (Exception ex) when (ex is DirectoryNotFoundException || ex is FileNotFoundException)
- {
- result = default(TModel);
- return false;
- }
-
- // deserialise model
- try
- {
- result = this.Deserialise<TModel>(json);
- return true;
- }
- catch (Exception ex)
- {
- string error = $"Can't parse JSON file at {fullPath}.";
-
- if (ex is JsonReaderException)
- {
- error += " This doesn't seem to be valid JSON.";
- if (json.Contains("“") || json.Contains("”"))
- error += " Found curly quotes in the text; note that only straight quotes are allowed in JSON.";
- }
- error += $"\nTechnical details: {ex.Message}";
- throw new JsonReaderException(error);
- }
- }
-
- /// <summary>Save to a JSON file.</summary>
- /// <typeparam name="TModel">The model type.</typeparam>
- /// <param name="fullPath">The absolete file path.</param>
- /// <param name="model">The model to save.</param>
- /// <exception cref="InvalidOperationException">The given path is empty or invalid.</exception>
- public void WriteJsonFile<TModel>(string fullPath, TModel model)
- where TModel : class
- {
- // validate
- if (string.IsNullOrWhiteSpace(fullPath))
- throw new ArgumentException("The file path is empty or invalid.", nameof(fullPath));
-
- // create directory if needed
- string dir = Path.GetDirectoryName(fullPath);
- if (dir == null)
- throw new ArgumentException("The file path is invalid.", nameof(fullPath));
- if (!Directory.Exists(dir))
- Directory.CreateDirectory(dir);
-
- // write file
- string json = this.Serialise(model);
- File.WriteAllText(fullPath, json);
- }
-
- /// <summary>Deserialize JSON text if possible.</summary>
- /// <typeparam name="TModel">The model type.</typeparam>
- /// <param name="json">The raw JSON text.</param>
- public TModel Deserialise<TModel>(string json)
- {
- try
- {
- return JsonConvert.DeserializeObject<TModel>(json, this.JsonSettings);
- }
- catch (JsonReaderException)
- {
- // try replacing curly quotes
- if (json.Contains("“") || json.Contains("”"))
- {
- try
- {
- return JsonConvert.DeserializeObject<TModel>(json.Replace('“', '"').Replace('”', '"'), this.JsonSettings);
- }
- catch { /* rethrow original error */ }
- }
-
- throw;
- }
- }
-
- /// <summary>Serialize a model to JSON text.</summary>
- /// <typeparam name="TModel">The model type.</typeparam>
- /// <param name="model">The model to serialise.</param>
- /// <param name="formatting">The formatting to apply.</param>
- public string Serialise<TModel>(TModel model, Formatting formatting = Formatting.Indented)
- {
- return JsonConvert.SerializeObject(model, formatting, this.JsonSettings);
- }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/Models/Manifest.cs b/src/SMAPI.Toolkit/Serialisation/Models/Manifest.cs
deleted file mode 100644
index 6cb9496b..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Models/Manifest.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using StardewModdingAPI.Toolkit.Serialisation.Converters;
-
-namespace StardewModdingAPI.Toolkit.Serialisation.Models
-{
- /// <summary>A manifest which describes a mod for SMAPI.</summary>
- public class Manifest : IManifest
- {
- /*********
- ** Accessors
- *********/
- /// <summary>The mod name.</summary>
- public string Name { get; set; }
-
- /// <summary>A brief description of the mod.</summary>
- public string Description { get; set; }
-
- /// <summary>The mod author's name.</summary>
- public string Author { get; set; }
-
- /// <summary>The mod version.</summary>
- public ISemanticVersion Version { get; set; }
-
- /// <summary>The minimum SMAPI version required by this mod, if any.</summary>
- public ISemanticVersion MinimumApiVersion { get; set; }
-
- /// <summary>The name of the DLL in the directory that has the <c>Entry</c> method. Mutually exclusive with <see cref="ContentPackFor"/>.</summary>
- public string EntryDll { get; set; }
-
- /// <summary>The mod which will read this as a content pack. Mutually exclusive with <see cref="Manifest.EntryDll"/>.</summary>
- [JsonConverter(typeof(ManifestContentPackForConverter))]
- public IManifestContentPackFor ContentPackFor { get; set; }
-
- /// <summary>The other mods that must be loaded before this mod.</summary>
- [JsonConverter(typeof(ManifestDependencyArrayConverter))]
- public IManifestDependency[] Dependencies { get; set; }
-
- /// <summary>The namespaced mod IDs to query for updates (like <c>Nexus:541</c>).</summary>
- public string[] UpdateKeys { get; set; }
-
- /// <summary>The unique mod ID.</summary>
- public string UniqueID { get; set; }
-
- /// <summary>Any manifest fields which didn't match a valid field.</summary>
- [JsonExtensionData]
- public IDictionary<string, object> ExtraFields { get; set; }
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- public Manifest() { }
-
- /// <summary>Construct an instance for a transitional content pack.</summary>
- /// <param name="uniqueID">The unique mod ID.</param>
- /// <param name="name">The mod name.</param>
- /// <param name="author">The mod author's name.</param>
- /// <param name="description">A brief description of the mod.</param>
- /// <param name="version">The mod version.</param>
- /// <param name="contentPackFor">The modID which will read this as a content pack.</param>
- 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/SMAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs b/src/SMAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs
deleted file mode 100644
index d0e42216..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Models/ManifestContentPackFor.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace StardewModdingAPI.Toolkit.Serialisation.Models
-{
- /// <summary>Indicates which mod can read the content pack represented by the containing manifest.</summary>
- public class ManifestContentPackFor : IManifestContentPackFor
- {
- /*********
- ** Accessors
- *********/
- /// <summary>The unique ID of the mod which can read this content pack.</summary>
- public string UniqueID { get; set; }
-
- /// <summary>The minimum required version (if any).</summary>
- public ISemanticVersion MinimumVersion { get; set; }
- }
-}
diff --git a/src/SMAPI.Toolkit/Serialisation/Models/ManifestDependency.cs b/src/SMAPI.Toolkit/Serialisation/Models/ManifestDependency.cs
deleted file mode 100644
index 8db58d5d..00000000
--- a/src/SMAPI.Toolkit/Serialisation/Models/ManifestDependency.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace StardewModdingAPI.Toolkit.Serialisation.Models
-{
- /// <summary>A mod dependency listed in a mod manifest.</summary>
- public class ManifestDependency : IManifestDependency
- {
- /*********
- ** Accessors
- *********/
- /// <summary>The unique mod ID to require.</summary>
- public string UniqueID { get; set; }
-
- /// <summary>The minimum required version (if any).</summary>
- public ISemanticVersion MinimumVersion { get; set; }
-
- /// <summary>Whether the dependency must be installed to use the mod.</summary>
- public bool IsRequired { get; set; }
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- /// <param name="uniqueID">The unique mod ID to require.</param>
- /// <param name="minimumVersion">The minimum required version (if any).</param>
- /// <param name="required">Whether the dependency must be installed to use the mod.</param>
- 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.Toolkit/Serialisation/SParseException.cs b/src/SMAPI.Toolkit/Serialisation/SParseException.cs
deleted file mode 100644
index 61a7b305..00000000
--- a/src/SMAPI.Toolkit/Serialisation/SParseException.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace StardewModdingAPI.Toolkit.Serialisation
-{
- /// <summary>A format exception which provides a user-facing error message.</summary>
- internal class SParseException : FormatException
- {
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- /// <param name="message">The error message.</param>
- /// <param name="ex">The underlying exception, if any.</param>
- public SParseException(string message, Exception ex = null)
- : base(message, ex) { }
- }
-}