github.com/thetreep/go-swagger@v0.0.0-20240223100711-35af64f14f01/cmd/swagger/commands/diff/array_diff.go (about) 1 package diff 2 3 // This is a simple DSL for diffing arrays 4 5 // fromArrayStruct utility struct to encompass diffing of string arrays 6 type fromArrayStruct struct { 7 from []string 8 } 9 10 // fromStringArray starts a fluent diff expression 11 func fromStringArray(from []string) fromArrayStruct { 12 return fromArrayStruct{from} 13 } 14 15 // DiffsTo completes a fluent diff expression 16 func (f fromArrayStruct) DiffsTo(toArray []string) (added, deleted, common []string) { 17 inFrom := 1 18 inTo := 2 19 20 if f.from == nil { 21 return toArray, []string{}, []string{} 22 } 23 24 m := make(map[string]int, len(toArray)) 25 added = make([]string, 0, len(toArray)) 26 deleted = make([]string, 0, len(f.from)) 27 common = make([]string, 0, len(f.from)) 28 29 for _, item := range f.from { 30 m[item] = inFrom 31 } 32 33 for _, item := range toArray { 34 if _, ok := m[item]; ok { 35 m[item] |= inTo 36 } else { 37 m[item] = inTo 38 } 39 } 40 for key, val := range m { 41 switch val { 42 case inFrom: 43 deleted = append(deleted, key) 44 case inTo: 45 added = append(added, key) 46 default: 47 common = append(common, key) 48 } 49 } 50 return 51 } 52 53 // fromMapStruct utility struct to encompass diffing of string arrays 54 type fromMapStruct struct { 55 srcMap map[string]interface{} 56 } 57 58 // fromStringMap starts a comparison by declaring a source map 59 func fromStringMap(srcMap map[string]interface{}) fromMapStruct { 60 return fromMapStruct{srcMap} 61 } 62 63 // Pair stores a pair of items which share a key in two maps 64 type Pair struct { 65 First interface{} 66 Second interface{} 67 } 68 69 // DiffsTo - generates diffs for a comparison 70 func (f fromMapStruct) DiffsTo(destMap map[string]interface{}) (added, deleted, common map[string]interface{}) { 71 added = make(map[string]interface{}) 72 deleted = make(map[string]interface{}) 73 common = make(map[string]interface{}) 74 75 inSrc := 1 76 inDest := 2 77 78 m := make(map[string]int) 79 80 // enter values for all items in the source array 81 for key := range f.srcMap { 82 m[key] = inSrc 83 } 84 85 // now either set or 'boolean or' a new flag if in the second collection 86 for key := range destMap { 87 if _, ok := m[key]; ok { 88 m[key] |= inDest 89 } else { 90 m[key] = inDest 91 } 92 } 93 // finally inspect the values and generate the left,right and shared collections 94 // for the shared items, store both values in case there's a diff 95 for key, val := range m { 96 switch val { 97 case inSrc: 98 deleted[key] = f.srcMap[key] 99 case inDest: 100 added[key] = destMap[key] 101 default: 102 common[key] = Pair{f.srcMap[key], destMap[key]} 103 } 104 } 105 return added, deleted, common 106 }