using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace RioJoy.Core.Profiles;
///
/// Loads and saves as JSON. Replaces the legacy
/// SimpleIni single-file config with a profile library (see docs/PLAN.md).
/// Newtonsoft rather than System.Text.Json so the net40 (Windows XP) flavor
/// shares one serializer โ and one on-disk format โ with net48 (PLAN.md ยง8A).
/// Conventions match the original STJ settings: indented, PascalCase names,
/// enums as strings, nulls skipped โ existing config.json files parse as-is.
///
public static class ConfigStore
{
private static readonly JsonSerializerSettings Options = new()
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
Converters = { new StringEnumConverter() },
};
public static string Serialize(AppConfig config)
{
if (config is null) throw new ArgumentNullException(nameof(config));
return JsonConvert.SerializeObject(config, Options);
}
public static AppConfig Deserialize(string json)
{
if (string.IsNullOrWhiteSpace(json)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(json));
return JsonConvert.DeserializeObject(json, Options)
?? throw new JsonSerializationException("Config JSON deserialized to null.");
}
/// Save the config to (creating directories).
public static void Save(AppConfig config, string path)
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(path));
string? dir = Path.GetDirectoryName(Path.GetFullPath(path));
if (!string.IsNullOrEmpty(dir))
Directory.CreateDirectory(dir);
File.WriteAllText(path, Serialize(config));
}
///
/// Load the config from , or return a fresh default
/// if the file does not exist.
///
public static AppConfig Load(string path)
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(path));
return File.Exists(path) ? Deserialize(File.ReadAllText(path)) : new AppConfig();
}
}