(changes *[]FieldChange, tokens []string, oldNode, newNode interface{})
| 247 | } |
| 248 | |
| 249 | func diffArrayNodes(changes *[]FieldChange, tokens []string, oldNode, newNode interface{}) error { |
| 250 | oldArr, _ := oldNode.([]interface{}) |
| 251 | newArr, _ := newNode.([]interface{}) |
| 252 | |
| 253 | maxLen := len(oldArr) |
| 254 | if len(newArr) > maxLen { |
| 255 | maxLen = len(newArr) |
| 256 | } |
| 257 | |
| 258 | for i := 0; i < maxLen; i++ { |
| 259 | next := append(tokens, strconv.Itoa(i)) |
| 260 | var oldVal interface{} |
| 261 | var newVal interface{} |
| 262 | if i < len(oldArr) { |
| 263 | oldVal = oldArr[i] |
| 264 | } |
| 265 | if i < len(newArr) { |
| 266 | newVal = newArr[i] |
| 267 | } |
| 268 | |
| 269 | switch { |
| 270 | case oldVal != nil && newVal != nil: |
| 271 | if reflect.DeepEqual(oldVal, newVal) { |
| 272 | continue |
| 273 | } |
| 274 | subPatch, err := createNodePatch(oldVal, newVal) |
| 275 | if err != nil { |
| 276 | return err |
| 277 | } |
| 278 | if subPatch == nil { |
| 279 | path, field := splitTokens(next) |
| 280 | *changes = append(*changes, FieldChange{ |
| 281 | Path: path, |
| 282 | Field: field, |
| 283 | Change: "replace", |
| 284 | OldValue: oldVal, |
| 285 | NewValue: newVal, |
| 286 | }) |
| 287 | continue |
| 288 | } |
| 289 | if err := walkPatch(changes, next, subPatch, oldVal, newVal); err != nil { |
| 290 | return err |
| 291 | } |
| 292 | case oldVal != nil: |
| 293 | path, field := splitTokens(next) |
| 294 | *changes = append(*changes, FieldChange{ |
| 295 | Path: path, |
| 296 | Field: field, |
| 297 | Change: "remove", |
| 298 | OldValue: oldVal, |
| 299 | }) |
| 300 | case newVal != nil: |
| 301 | path, field := splitTokens(next) |
| 302 | *changes = append(*changes, FieldChange{ |
| 303 | Path: path, |
| 304 | Field: field, |
| 305 | Change: "add", |
| 306 | NewValue: newVal, |
no test coverage detected