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 }