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  }