github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/utils/compare.go (about)

     1  // Copyright (c) 2019 HyperHQ Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package utils
     7  
     8  import "reflect"
     9  
    10  func compareStruct(foo, bar reflect.Value) bool {
    11  	for i := 0; i < foo.NumField(); i++ {
    12  		if !deepCompareValue(foo.Field(i), bar.Field(i)) {
    13  			return false
    14  		}
    15  	}
    16  
    17  	return true
    18  }
    19  
    20  func compareMap(foo, bar reflect.Value) bool {
    21  	if foo.Len() != bar.Len() {
    22  		return false
    23  	}
    24  
    25  	for _, k := range foo.MapKeys() {
    26  		if !deepCompareValue(foo.MapIndex(k), bar.MapIndex(k)) {
    27  			return false
    28  		}
    29  	}
    30  
    31  	return true
    32  }
    33  
    34  func compareSlice(foo, bar reflect.Value) bool {
    35  	if foo.Len() != bar.Len() {
    36  		return false
    37  	}
    38  	for j := 0; j < foo.Len(); j++ {
    39  		if !deepCompareValue(foo.Index(j), bar.Index(j)) {
    40  			return false
    41  		}
    42  	}
    43  	return true
    44  }
    45  
    46  func deepCompareValue(foo, bar reflect.Value) bool {
    47  	if !foo.IsValid() || !bar.IsValid() {
    48  		return foo.IsValid() == bar.IsValid()
    49  	}
    50  
    51  	if foo.Type() != bar.Type() {
    52  		return false
    53  	}
    54  	switch foo.Kind() {
    55  	case reflect.Map:
    56  		return compareMap(foo, bar)
    57  	case reflect.Array:
    58  		fallthrough
    59  	case reflect.Slice:
    60  		return compareSlice(foo, bar)
    61  	case reflect.Struct:
    62  		return compareStruct(foo, bar)
    63  	case reflect.Interface:
    64  		return reflect.DeepEqual(foo.Interface(), bar.Interface())
    65  	default:
    66  		return foo.Interface() == bar.Interface()
    67  	}
    68  }
    69  
    70  // DeepCompare compare foo and bar.
    71  func DeepCompare(foo, bar interface{}) bool {
    72  	v1 := reflect.ValueOf(foo)
    73  	v2 := reflect.ValueOf(bar)
    74  
    75  	return deepCompareValue(v1, v2)
    76  }