Files
configkit/internal/engine/resolution_compare.go

61 lines
2.1 KiB
Go

package engine
import "go.maximumdirect.net/configkit/internal/document"
// compareResolutionValues reports field-level changes at stable list positions.
func compareResolutionValues(before, after *document.Node, correspondence ...resolutionCorrespondence) []documentDelta {
var deltas []documentDelta
var compare func(*document.Node, *document.Node, Path)
compare = func(left, right *document.Node, path Path) {
if left == nil || right == nil || left.Kind != right.Kind {
compareConfigurationValue(left, right, path, &deltas)
return
}
switch left.Kind {
case document.Mapping:
leftEntries := make(map[string]*document.Node, len(left.Mapping))
for _, entry := range left.Mapping {
leftEntries[entry.Key] = entry.Value
}
for _, entry := range right.Mapping {
compare(leftEntries[entry.Key], entry.Value, path.Key(entry.Key))
delete(leftEntries, entry.Key)
}
for key, value := range leftEntries {
compare(value, nil, path.Key(key))
}
case document.Sequence:
if len(correspondence) != 0 {
if collection, registered := correspondence[0].collections[path.String()]; registered {
if !collection.eligible {
if !configurationValuesEqual(left, right) {
deltas = append(deltas, documentDelta{path: path.clone(), kind: documentReplaced})
}
return
}
if collection.structural {
deltas = append(deltas, documentDelta{path: path.clone(), kind: documentReplaced})
}
for finalIndex, entryIndex := range collection.finalToEntry {
if entryIndex >= 0 {
compare(left.Sequence[entryIndex], right.Sequence[finalIndex], path.Index(finalIndex))
}
}
return
}
}
if len(left.Sequence) != len(right.Sequence) {
deltas = append(deltas, documentDelta{path: path.clone(), kind: documentReplaced})
return
}
for index := range left.Sequence {
compare(left.Sequence[index], right.Sequence[index], path.Index(index))
}
default:
compareConfigurationValue(left, right, path, &deltas)
}
}
compare(before, after, Path{})
return sortDocumentDeltas(deltas)
}