diff options
Diffstat (limited to 'src/SMAPI.Toolkit/Serialization/JsonHelper.cs')
-rw-r--r-- | src/SMAPI.Toolkit/Serialization/JsonHelper.cs | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/SMAPI.Toolkit/Serialization/JsonHelper.cs b/src/SMAPI.Toolkit/Serialization/JsonHelper.cs index 00db9903..3c9308f2 100644 --- a/src/SMAPI.Toolkit/Serialization/JsonHelper.cs +++ b/src/SMAPI.Toolkit/Serialization/JsonHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -14,7 +15,7 @@ namespace StardewModdingAPI.Toolkit.Serialization ** Accessors *********/ /// <summary>The JSON settings to use when serializing and deserializing files.</summary> - public JsonSerializerSettings JsonSettings { get; } = new JsonSerializerSettings + public JsonSerializerSettings JsonSettings { get; } = new() { Formatting = Formatting.Indented, ObjectCreationHandling = ObjectCreationHandling.Replace, // avoid issue where default ICollection<T> values are duplicated each time the config is loaded @@ -36,7 +37,12 @@ namespace StardewModdingAPI.Toolkit.Serialization /// <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) + public bool ReadJsonFileIfExists<TModel>(string fullPath, +#if NET5_0_OR_GREATER + [NotNullWhen(true)] +#endif + out TModel? result + ) { // validate if (string.IsNullOrWhiteSpace(fullPath)) @@ -48,9 +54,9 @@ namespace StardewModdingAPI.Toolkit.Serialization { json = File.ReadAllText(fullPath); } - catch (Exception ex) when (ex is DirectoryNotFoundException || ex is FileNotFoundException) + catch (Exception ex) when (ex is DirectoryNotFoundException or FileNotFoundException) { - result = default(TModel); + result = default; return false; } @@ -58,7 +64,7 @@ namespace StardewModdingAPI.Toolkit.Serialization try { result = this.Deserialize<TModel>(json); - return true; + return result != null; } catch (Exception ex) { @@ -88,7 +94,7 @@ namespace StardewModdingAPI.Toolkit.Serialization throw new ArgumentException("The file path is empty or invalid.", nameof(fullPath)); // create directory if needed - string dir = Path.GetDirectoryName(fullPath); + string dir = Path.GetDirectoryName(fullPath)!; if (dir == null) throw new ArgumentException("The file path is invalid.", nameof(fullPath)); if (!Directory.Exists(dir)) @@ -106,7 +112,8 @@ namespace StardewModdingAPI.Toolkit.Serialization { try { - return JsonConvert.DeserializeObject<TModel>(json, this.JsonSettings); + return JsonConvert.DeserializeObject<TModel>(json, this.JsonSettings) + ?? throw new InvalidOperationException($"Couldn't deserialize model type '{typeof(TModel)}' from empty or null JSON."); } catch (JsonReaderException) { @@ -115,7 +122,8 @@ namespace StardewModdingAPI.Toolkit.Serialization { try { - return JsonConvert.DeserializeObject<TModel>(json.Replace('“', '"').Replace('”', '"'), this.JsonSettings); + return JsonConvert.DeserializeObject<TModel>(json.Replace('“', '"').Replace('”', '"'), this.JsonSettings) + ?? throw new InvalidOperationException($"Couldn't deserialize model type '{typeof(TModel)}' from empty or null JSON."); } catch { /* rethrow original error */ } } |