package configkit import "gitea.maximumdirect.net/eric/ConfigKit/internal/engine" // Difference describes one canonical changed region between two successful // loads. Left is the earlier value and Right is the later value. Each snapshot // is detached; Present distinguishes absence from an explicit null, and // Redacted reports whether combined sensitivity affected that side. Mappings // are compared recursively, while sequences are reported as atomic values. // Records are ordered by canonical JSON pointer. HiddenChanged indicates that // a value concealed by combined sensitivity changed, without revealing which // concealed member changed. type Difference struct { Path Path Left ValueSnapshot Right ValueSnapshot HiddenChanged bool } // Diff compares the frozen effective values of two successful loads of the // same configuration type. It does not reread sources, environment variables, // or rerun defaults or resolvers. Equal values produce no records even when // their sources, defaults, or resolution histories differ. Credential contents // are not compared: typed secret references compare by reference name only. // // Both results must be non-nil successful loads with inspection state; nil or // zero results return an error and no records. Load errors are returned by // Load, so callers must handle those before calling Diff. Snapshots are safe // for presentation but are not a complete reloadable configuration. func Diff[T any](left, right *Result[T]) ([]Difference, error) { var leftInspection, rightInspection *engine.Inspection if left != nil { leftInspection = left.inspection } if right != nil { rightInspection = right.inspection } values, err := engine.Diff(leftInspection, rightInspection) if err != nil { return nil, err } differences := make([]Difference, len(values)) for index, value := range values { differences[index] = Difference{ Path: fromEnginePath(value.Path), Left: fromEngineValueSnapshot(value.Left), Right: fromEngineValueSnapshot(value.Right), HiddenChanged: value.HiddenChanged, } } return differences, nil }