feat: add typed production settings contract
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PRecAnnot.Core;
|
||||
|
||||
/// <summary>Typed projection of the release Settings.xml sections consumed by production workflows.</summary>
|
||||
public sealed record ProductionSettingsContract(
|
||||
IReadOnlyList<NamedDrawingObject> CopyMissingObjects,
|
||||
IReadOnlyList<LayerSetupRule> LayerSetup,
|
||||
string AnnotationLayer,
|
||||
string AnnotationTextStyle,
|
||||
string AnnotationLeaderStyle,
|
||||
string ConnectionPolylineLayer,
|
||||
string ConnectionTextLayer,
|
||||
string ConnectionTextStyle,
|
||||
string ElevationLayer,
|
||||
string ElevationTextStyle,
|
||||
string SetLayer,
|
||||
double? FixedSupportPlusLength,
|
||||
string? ScriptFolder)
|
||||
{
|
||||
public static ProductionSettingsContract Parse(string xml)
|
||||
{
|
||||
var root = XElement.Parse(xml, LoadOptions.PreserveWhitespace);
|
||||
var copy = root.Element("CopyMissingObjects")?.Elements("Object")
|
||||
.Select(value => new NamedDrawingObject(Required(value, "type"), Required(value, "name")))
|
||||
.ToArray() ?? Array.Empty<NamedDrawingObject>();
|
||||
var layers = root.Element("LayersSetup")?.Elements("LayerSetup")
|
||||
.Select(value => new LayerSetupRule(
|
||||
Required(value, "filtertype"), Required(value, "filtervalue", allowEmpty: true),
|
||||
ParseInt(value, "lineweight"), Required(value, "linetype", allowEmpty: true),
|
||||
Required(value, "color", allowEmpty: true)))
|
||||
.ToArray() ?? Array.Empty<LayerSetupRule>();
|
||||
var annotations = root.Element("Annotations");
|
||||
var connections = root.Element("LinenumberConnections");
|
||||
var elevations = root.Element("Elevations");
|
||||
var setLayer = root.Element("SetLayer")?.Attribute("name")?.Value;
|
||||
if (string.IsNullOrWhiteSpace(setLayer)) throw Invalid("SetLayer.name");
|
||||
var plusLength = root.Element("PlusLengthNO")?.Attribute("value")?.Value;
|
||||
double? parsedPlusLength = double.TryParse(plusLength, NumberStyles.Float, CultureInfo.InvariantCulture, out var plus) ? plus : null;
|
||||
return new(
|
||||
copy,
|
||||
layers,
|
||||
Required(annotations, "layer"),
|
||||
Required(annotations, "textstyle"),
|
||||
Required(annotations, "multileaderstyle"),
|
||||
Required(connections, "polylinelayer"),
|
||||
Required(connections, "textlayer"),
|
||||
Required(connections, "textstyle"),
|
||||
Required(elevations, "layer"),
|
||||
Required(elevations, "textstyle"),
|
||||
setLayer,
|
||||
parsedPlusLength,
|
||||
root.Element("ScriptFolder")?.Attribute("path")?.Value);
|
||||
}
|
||||
|
||||
private static int? ParseInt(XElement value, string name) => int.TryParse(value.Attribute(name)?.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) ? parsed : null;
|
||||
private static string Required(XElement? value, string name, bool allowEmpty = false) => value?.Attribute(name) is { Value: var result } && (allowEmpty || !string.IsNullOrWhiteSpace(result)) ? result : throw Invalid(name);
|
||||
private static InvalidDataException Invalid(string field) => new("PRODUCTION_SETTINGS_INVALID:" + field);
|
||||
}
|
||||
|
||||
public sealed record NamedDrawingObject(string Type, string Name);
|
||||
public sealed record LayerSetupRule(string FilterType, string FilterValue, int? LineWeight, string LineType, string Color);
|
||||
Reference in New Issue
Block a user