func diffMaps(dq *diffQueue, w io.Writer, p types.Path, v1, v2 types.Map) { wroteHeader := false added, removed, modified := v2.Diff(v1) for _, k := range added { wroteHeader = writeHeader(w, wroteHeader, p) line(w, addPrefix, k, v2.Get(k)) } for _, k := range removed { wroteHeader = writeHeader(w, wroteHeader, p) line(w, subPrefix, k, v1.Get(k)) } for _, k := range modified { c1, c2 := v1.Get(k), v2.Get(k) if canCompare(c1, c2) { buf := bytes.NewBuffer(nil) d.Exp.NoError(types.WriteEncodedValueWithTags(buf, k)) p1 := p.AddField(buf.String()) dq.PushBack(diffInfo{path: p1, key: k, v1: c1, v2: c2}) } else { wroteHeader = writeHeader(w, wroteHeader, p) line(w, subPrefix, k, v1.Get(k)) line(w, addPrefix, k, v2.Get(k)) } } writeFooter(w, wroteHeader) }
func diffMaps(w io.Writer, p types.Path, v1, v2 types.Map) { changeChan := make(chan types.ValueChanged) stopChan := make(chan struct{}, 1) // buffer size of 1, so this won't block if diff already finished defer stop(stopChan) go func() { v2.Diff(v1, changeChan, stopChan) close(changeChan) }() wroteHeader := false for change := range changeChan { switch change.ChangeType { case types.DiffChangeAdded: wroteHeader = writeHeader(w, wroteHeader, p) line(w, ADD, change.V, v2.Get(change.V)) case types.DiffChangeRemoved: wroteHeader = writeHeader(w, wroteHeader, p) line(w, DEL, change.V, v1.Get(change.V)) case types.DiffChangeModified: c1, c2 := v1.Get(change.V), v2.Get(change.V) if shouldDescend(c1, c2) { wroteHeader = writeFooter(w, wroteHeader) diff(w, p.AddIndex(change.V), change.V, c1, c2) } else { wroteHeader = writeHeader(w, wroteHeader, p) line(w, DEL, change.V, c1) line(w, ADD, change.V, c2) } default: panic("unknown change type") } } writeFooter(w, wroteHeader) }
func diffSummaryMap(ch chan<- diffSummaryProgress, v1, v2 types.Map) { diffSummaryValueChanged(ch, v1.Len(), v2.Len(), func(changeChan chan<- types.ValueChanged, stopChan <-chan struct{}) { v2.Diff(v1, changeChan, stopChan) }) }