feat: add p-rec-annot datalinks line-number read path
This commit is contained in:
@@ -52,6 +52,10 @@ public interface ILineNumberAnnotationFormatter
|
|||||||
LineNumberFormattingResult Format(LineNumberAnnotationDefinition definition, IReadOnlyDictionary<string, string?> fields);
|
LineNumberFormattingResult Format(LineNumberAnnotationDefinition definition, IReadOnlyDictionary<string, string?> fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed record DataLinksPropertyReadResult(bool Success, IReadOnlyDictionary<string, string?> Properties, string? FailureCode = null);
|
||||||
|
public interface IDataLinksPropertyReader { DataLinksPropertyReadResult ReadProperties(long rowId); }
|
||||||
|
public sealed record LineNumberFieldResolution(bool Success, IReadOnlyDictionary<string, string?> Values, string? FailureCode = null);
|
||||||
|
|
||||||
public sealed record GeometrySnapshot
|
public sealed record GeometrySnapshot
|
||||||
{
|
{
|
||||||
public Point3Dto? WorldPosition { get; init; }
|
public Point3Dto? WorldPosition { get; init; }
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
namespace PRecAnnot.Core;
|
||||||
|
|
||||||
|
public sealed class LineNumberFieldResolver(IDataLinksPropertyReader reader)
|
||||||
|
{
|
||||||
|
// Source-backed Convert_field_to_value port. The adapter supplies a
|
||||||
|
// deterministic, read-only flattened key set: Table.Column and Column.
|
||||||
|
public LineNumberFieldResolution Resolve(long rowId, IEnumerable<string> fields)
|
||||||
|
{
|
||||||
|
var read = reader.ReadProperties(rowId);
|
||||||
|
if (!read.Success) return new(false, new Dictionary<string, string?>(), read.FailureCode ?? "DATALINKS_READ_FAILED");
|
||||||
|
var values = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (var field in fields.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(field)) return new(false, values, "LINE_NUMBER_FIELD_EMPTY");
|
||||||
|
var dot = field.IndexOf('.', StringComparison.Ordinal);
|
||||||
|
if (dot <= 0 || dot == field.Length - 1) return new(false, values, "LINE_NUMBER_FIELD_INVALID:" + field);
|
||||||
|
if (!read.Properties.TryGetValue(field, out var value) && !read.Properties.TryGetValue(field[(dot + 1)..], out value)) return new(false, values, "LINE_NUMBER_COLUMN_MISSING:" + field);
|
||||||
|
values[field] = value ?? string.Empty;
|
||||||
|
}
|
||||||
|
return new(true, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Autodesk.ProcessPower.DataLinks;
|
||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
namespace PRecAnnot.Plant3D2026;
|
||||||
|
|
||||||
|
internal sealed class PlantDataLinksPropertyReader(DataLinksManager dataLinks) : IDataLinksPropertyReader
|
||||||
|
{
|
||||||
|
public DataLinksPropertyReadResult ReadProperties(long rowId)
|
||||||
|
{
|
||||||
|
if (rowId <= 0) return new(false, new Dictionary<string, string?>(), "DATALINKS_ROW_ID_INVALID");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var values = dataLinks.GetAllProperties((int)rowId, true)
|
||||||
|
.GroupBy(x => x.Key, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToDictionary(x => x.Key, x => (string?)x.Last().Value, StringComparer.OrdinalIgnoreCase);
|
||||||
|
return new(true, values);
|
||||||
|
}
|
||||||
|
catch (DLException) { return new(false, new Dictionary<string, string?>(), "DATALINKS_PROPERTY_READ_FAILED"); }
|
||||||
|
catch (Exception) { return new(false, new Dictionary<string, string?>(), "DATALINKS_PROPERTY_READ_FAILED"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
using PRecAnnot.Core;
|
||||||
|
namespace PRecAnnot.Core.Tests;
|
||||||
|
public sealed class LineNumberFieldResolverTests
|
||||||
|
{
|
||||||
|
[Fact] public void ResolvesNullAsLegacyEmptyString() => Assert.Equal(string.Empty, new LineNumberFieldResolver(new Reader(true, new Dictionary<string,string?> { ["EngineeringItems.LineNumber"] = null })).Resolve(5, ["EngineeringItems.LineNumber"]).Values["EngineeringItems.LineNumber"]);
|
||||||
|
[Fact] public void RejectsInvalidField() => Assert.Equal("LINE_NUMBER_FIELD_INVALID:LineNumber", new LineNumberFieldResolver(new Reader(true, new Dictionary<string, string?>())).Resolve(5, ["LineNumber"]).FailureCode);
|
||||||
|
[Fact] public void PropagatesAdapterFailure() => Assert.Equal("DATALINKS_PROPERTY_READ_FAILED", new LineNumberFieldResolver(new Reader(false, new Dictionary<string, string?>())).Resolve(5, ["EngineeringItems.LineNumber"]).FailureCode);
|
||||||
|
private sealed record Reader(bool Ok, IReadOnlyDictionary<string,string?> Values) : IDataLinksPropertyReader { public DataLinksPropertyReadResult ReadProperties(long _) => new(Ok, Values, Ok ? null : "DATALINKS_PROPERTY_READ_FAILED"); }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user