Phase 8A (1/2): de-Span the serial layer, swap JSON to Newtonsoft

Prepares RioJoy.Core for the net40 (Windows XP) target, which has no
System.Memory, ValueTask, or System.Text.Json:
- IRioTransport and the whole protocol/framing layer now use byte[] +
  Task (RioPacket.Payload, PacketParser/Builder, RioChecksum, replies,
  AnalogReport, RioHidReport). At 9600 baud Span bought nothing; the
  SerialPortTransport bridge copies disappear entirely.
- ConfigStore/OverlayTemplateStore switch to Newtonsoft 13 with the
  same conventions (indented, PascalCase, string enums, null-skipping);
  verified against the real STJ-written config.json and regions.json
  (load + round-trip). System.Memory and System.Text.Json packages
  dropped.

275 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-11 20:36:19 -05:00
co-authored by Claude Fable 5
parent 02abfa8a14
commit 3b2af7b79a
21 changed files with 104 additions and 93 deletions
+13 -9
View File
@@ -1,32 +1,36 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace RioJoy.Core.Profiles;
/// <summary>
/// Loads and saves <see cref="AppConfig"/> 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.
/// </summary>
public static class ConfigStore
{
private static readonly JsonSerializerOptions Options = new()
private static readonly JsonSerializerSettings Options = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter() },
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 JsonSerializer.Serialize(config, Options);
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 JsonSerializer.Deserialize<AppConfig>(json, Options)
?? throw new JsonException("Config JSON deserialized to null.");
return JsonConvert.DeserializeObject<AppConfig>(json, Options)
?? throw new JsonSerializationException("Config JSON deserialized to null.");
}
/// <summary>Save the config to <paramref name="path"/> (creating directories).</summary>