Centralize D&D source reference ordering

This commit is contained in:
2026-07-24 14:20:10 +00:00
parent 6e21c83fd8
commit 1ff449435f
16 changed files with 363 additions and 460 deletions

View File

@@ -118,7 +118,8 @@ func (n *Normalizer) Normalize(ctx context.Context, req contracts.TypedNormalize
if !registry.Bound() {
return contracts.TypedNormalizeResult[dnd.NPCInteractionList]{}, normalizerErrorf("NPC registry reference is required")
}
value, warnings := normalizeList(req.MergeOutput.Value, req.Source, registry)
order := shared.NewSourceRefOrder(req.Source)
value, warnings := normalizeList(req.MergeOutput.Value, req.Source, order, registry)
return contracts.TypedNormalizeResult[dnd.NPCInteractionList]{Value: value, Warnings: warnings}, nil
}
@@ -132,7 +133,7 @@ type nameCanonicalization struct {
to string
}
func normalizeList(input dnd.NPCInteractionList, doc *source.SourceDocument, registry *npcregistry.Registry) (dnd.NPCInteractionList, []contracts.Warning) {
func normalizeList(input dnd.NPCInteractionList, doc *source.SourceDocument, order shared.SourceRefOrder, registry *npcregistry.Registry) (dnd.NPCInteractionList, []contracts.Warning) {
if input.Interactions == nil {
return dnd.NPCInteractionList{}, nil
}
@@ -140,7 +141,7 @@ func normalizeList(input dnd.NPCInteractionList, doc *source.SourceDocument, reg
records := make([]normalizedRecord, len(input.Interactions))
warnings := make([]contracts.Warning, 0)
for index, inputInteraction := range input.Interactions {
interaction, nameChange, refsChanged := normalizeInteraction(inputInteraction, doc, registry)
interaction, nameChange, refsChanged := normalizeInteraction(inputInteraction, order, registry)
records[index] = normalizedRecord{interaction: interaction, inputIndex: index}
if nameChange != nil {
warnings = append(warnings, contracts.Warning{
@@ -161,7 +162,7 @@ func normalizeList(input dnd.NPCInteractionList, doc *source.SourceDocument, reg
}
sort.SliceStable(records, func(left, right int) bool {
return interactionmodel.Less(doc, records[left].interaction, records[right].interaction)
return interactionmodel.Less(order, records[left].interaction, records[right].interaction)
})
for position, record := range records {
if position == record.inputIndex {
@@ -180,7 +181,7 @@ func normalizeList(input dnd.NPCInteractionList, doc *source.SourceDocument, reg
diagnostics.LimitWarnings(warnings, "npc_interactions", ReasonCodeWarningsOmitted)
}
func normalizeInteraction(input dnd.NPCInteraction, doc *source.SourceDocument, registry *npcregistry.Registry) (dnd.NPCInteraction, *nameCanonicalization, bool) {
func normalizeInteraction(input dnd.NPCInteraction, order shared.SourceRefOrder, registry *npcregistry.Registry) (dnd.NPCInteraction, *nameCanonicalization, bool) {
output := cloneInteraction(input)
if canonical, ok := registry.Lookup(identity.NormalizeDisplay(input.Name)); ok {
output.Name = canonical.Name
@@ -189,7 +190,7 @@ func normalizeInteraction(input dnd.NPCInteraction, doc *source.SourceDocument,
if input.Name != output.Name {
nameChange = &nameCanonicalization{from: input.Name, to: output.Name}
}
output.SourceRefs = interactionmodel.CanonicalizeSourceRefs(doc, input.SourceRefs)
output.SourceRefs = order.Canonicalize(input.SourceRefs)
return output, nameChange, !interactionmodel.SourceRefsEqual(input.SourceRefs, output.SourceRefs)
}