Files
OpenNest/OpenNest.Data/LocalJsonProvider.cs
T
ajandClaude Opus 5.5 b550640ef0 refactor: merge duplicated geometry, settings-file and form helpers
Roslyn Bridge flagged these as copy-paste clusters; each pair now shares
one implementation so a fix lands everywhere at once:

- Shape.OffsetInward/OffsetOutward differed only in the target winding.
- BestFitFinder kept its own copy of SpatialQuery's arc-extreme points.
- SplitDrawingForm rebuilt DrawingSplitter's clip-region grid for preview.
- GeometryOptimizer's collinear/coradial finders (one misspelled
  GetCoradialArs) become one generic FindRelated.
- Five settings files repeated the write-with-retry loop, and two also
  repeated the unit parser and unreadable-file filter (SettingsFile).
- ClampsForm and SupportGridForm repeated their row/box builders.
- Vertical/HorizontalRemnantComparer share a RemnantComparer base.

Behavior is unchanged except that Engine/NestStorage settings loads now
also tolerate NotSupported/Security exceptions, matching the other
settings files' never-throw contract.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:59:47 -04:00

101 lines
2.6 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
namespace OpenNest.Data;
public class LocalJsonProvider : IDataProvider
{
private readonly string _directory;
internal static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) },
};
public LocalJsonProvider(string directory)
{
_directory = directory;
Directory.CreateDirectory(_directory);
}
public IReadOnlyList<MachineSummary> GetMachines()
{
var summaries = new List<MachineSummary>();
foreach (var file in Directory.GetFiles(_directory, "*.json"))
{
var machine = ReadFile(file);
if (machine is not null)
summaries.Add(new MachineSummary(machine.Id, machine.Name));
}
return summaries;
}
public MachineConfig? GetMachine(Guid id)
{
var path = GetPath(id);
return File.Exists(path) ? ReadFile(path) : null;
}
public void SaveMachine(MachineConfig machine)
{
var json = JsonSerializer.Serialize(machine, JsonOptions);
var path = GetPath(machine.Id);
SettingsFile.Write(path, json);
}
public void DeleteMachine(Guid id)
{
var path = GetPath(id);
if (File.Exists(path))
File.Delete(path);
}
private string GetPath(Guid id) => Path.Combine(_directory, $"{id}.json");
private static MachineConfig? ReadFile(string path)
{
try
{
var json = File.ReadAllText(path);
return JsonSerializer.Deserialize<MachineConfig>(json, JsonOptions);
}
catch (JsonException)
{
return null;
}
catch (IOException)
{
return null;
}
}
public void EnsureDefaults()
{
if (Directory.GetFiles(_directory, "*.json").Length > 0)
return;
var assembly = typeof(LocalJsonProvider).Assembly;
var resourceName = assembly
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("Generic-Laser.json"));
if (resourceName is null)
return;
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream is null)
return;
using var reader = new StreamReader(stream);
var json = reader.ReadToEnd();
var config = JsonSerializer.Deserialize<MachineConfig>(json, JsonOptions);
if (config is null)
return;
SaveMachine(config);
}
}