Files
notarius/internal/modules/dnd/extract/spells/canonicalize.go

97 lines
2.7 KiB
Go

package spells
import (
"sort"
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
)
type orderedSpellResponse struct {
value spellCastResponse
earliest int
hasEvidence bool
}
func canonicalizeResponse(response *extractionResponse, order shared.SourceRefOrder, sourceID string) {
if response == nil {
return
}
ordered := make([]orderedSpellResponse, len(response.SpellCasts))
for index := range response.SpellCasts {
earliest, hasEvidence := canonicalizeSpellCast(&response.SpellCasts[index], order, sourceID)
ordered[index] = orderedSpellResponse{
value: response.SpellCasts[index],
earliest: earliest,
hasEvidence: hasEvidence,
}
}
sort.SliceStable(ordered, func(i, j int) bool {
if ordered[i].hasEvidence != ordered[j].hasEvidence {
return ordered[i].hasEvidence
}
if !ordered[i].hasEvidence {
return false
}
return ordered[i].earliest < ordered[j].earliest
})
for index := range ordered {
response.SpellCasts[index] = ordered[index].value
}
}
func canonicalizeSpellCast(spell *spellCastResponse, order shared.SourceRefOrder, sourceID string) (int, bool) {
if spell == nil {
return 0, false
}
refs := order.Canonicalize(spellSourceRefs(spell.SourceRefs, sourceID))
spell.SourceRefs = spellResponseRefs(refs)
return order.EarliestValid(refs)
}
func spellSourceRefs(refs []spellSourceRefResponse, sourceID string) []source.SourceRef {
if refs == nil {
return nil
}
values := make([]source.SourceRef, len(refs))
for index, ref := range refs {
values[index] = source.SourceRef{SourceID: sourceID, StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID}
}
return values
}
func spellResponseRefs(refs []source.SourceRef) []spellSourceRefResponse {
if refs == nil {
return nil
}
values := make([]spellSourceRefResponse, len(refs))
for index, ref := range refs {
values[index] = spellSourceRefResponse{StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID}
}
return values
}
func canonicalSpellList(response extractionResponse, sourceID string) dnd.SpellList {
spellCasts := make([]dnd.SpellCast, len(response.SpellCasts))
for index, spell := range response.SpellCasts {
refs := make([]source.SourceRef, len(spell.SourceRefs))
for refIndex, ref := range spell.SourceRefs {
refs[refIndex] = source.SourceRef{
SourceID: sourceID,
StartUnitID: ref.StartUnitID,
EndUnitID: ref.EndUnitID,
}
}
spellCasts[index] = dnd.SpellCast{
Caster: spell.Caster,
Spell: spell.Spell,
SourceRefs: refs,
}
}
if response.SpellCasts == nil {
spellCasts = nil
}
return dnd.SpellList{SpellCasts: spellCasts}
}