github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/utils.go (about)

     1  package generic
     2  
     3  import (
     4  	"reflect"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/cloudwego/dynamicgo/proto"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  var bytesType = reflect.TypeOf([]byte{})
    14  
    15  const (
    16  	none int = 0
    17  	b2s  int = 1
    18  	s2b  int = 2
    19  )
    20  
    21  func toInterface(v interface{}) interface{} {
    22  	return toInterface2(v, false, none)
    23  }
    24  
    25  func toInterface2(v interface{}, fieldId bool, byte2string int) interface{} {
    26  	vt := reflect.ValueOf(v)
    27  	if vt.Kind() == reflect.Ptr {
    28  		if vt.IsNil() {
    29  			return nil
    30  		}
    31  		vt = vt.Elem()
    32  	}
    33  	if k := vt.Kind(); k == reflect.Slice || k == reflect.Array {
    34  		if vt.Type() == bytesType {
    35  			if byte2string == b2s {
    36  				return string(vt.Bytes())
    37  			} else {
    38  				return vt.Bytes()
    39  			}
    40  		}
    41  		var r = make([]interface{}, 0, vt.Len())
    42  		for i := 0; i < vt.Len(); i++ {
    43  			vv := toInterface2(vt.Index(i).Interface(), fieldId, byte2string)
    44  			if vv != nil {
    45  				r = append(r, vv)
    46  			}
    47  		}
    48  		return r
    49  	} else if k == reflect.Map {
    50  		if kt := vt.Type().Key().Kind(); kt == reflect.String {
    51  			var r = make(map[string]interface{}, vt.Len())
    52  			for _, k := range vt.MapKeys() {
    53  				vv := toInterface2(vt.MapIndex(k).Interface(), fieldId, byte2string)
    54  				if vv != nil {
    55  					r[k.String()] = vv
    56  				}
    57  			}
    58  			return r
    59  		} else if kt == reflect.Int || kt == reflect.Int8 || kt == reflect.Int16 || kt == reflect.Int32 || kt == reflect.Int64 {
    60  			var r = make(map[int]interface{}, vt.Len())
    61  			for _, k := range vt.MapKeys() {
    62  				vv := toInterface2(vt.MapIndex(k).Interface(), fieldId, byte2string)
    63  				if vv != nil {
    64  					r[int(k.Int())] = vv
    65  				}
    66  			}
    67  			return r
    68  		} else {
    69  			var r = make(map[interface{}]interface{}, vt.Len())
    70  			for _, k := range vt.MapKeys() {
    71  				kv := toInterface2(k.Interface(), fieldId, byte2string)
    72  				vv := toInterface2(vt.MapIndex(k).Interface(), fieldId, byte2string)
    73  				if kv != nil && vv != nil {
    74  					switch t := kv.(type) {
    75  					case map[string]interface{}:
    76  						r[&t] = vv
    77  					case map[int]interface{}:
    78  						r[&t] = vv
    79  					case map[interface{}]interface{}:
    80  						r[&t] = vv
    81  					case []interface{}:
    82  						r[&t] = vv
    83  					default:
    84  						r[kv] = vv
    85  					}
    86  				}
    87  			}
    88  			return r
    89  		}
    90  	} else if k == reflect.Struct {
    91  		var r interface{}
    92  		if fieldId {
    93  			r = map[proto.FieldNumber]interface{}{}
    94  		} else {
    95  			r = map[int]interface{}{}
    96  		}
    97  		for i := 0; i < vt.NumField(); i++ {
    98  			field := vt.Type().Field(i)
    99  			if field.Name == "state" || field.Name == "unknownFields" || field.Name == "sizeCache" {
   100  				continue
   101  			}
   102  			tag := field.Tag.Get("protobuf")
   103  			ts := strings.Split(tag, ",")
   104  			id := i
   105  			if len(ts) > 1 {
   106  				id, _ = strconv.Atoi(ts[1])
   107  			}
   108  			vv := toInterface2(vt.Field(i).Interface(), fieldId, byte2string)
   109  			if vv != nil {
   110  				if fieldId {
   111  					r.(map[proto.FieldNumber]interface{})[proto.FieldNumber(id)] = vv
   112  				} else {
   113  					r.(map[int]interface{})[int(id)] = vv
   114  				}
   115  			}
   116  		}
   117  		return r
   118  	} else if k == reflect.Int || k == reflect.Int8 || k == reflect.Int16 || k == reflect.Int32 || k == reflect.Int64 {
   119  		return int(vt.Int())
   120  	} else if k == reflect.String {
   121  		if byte2string == s2b {
   122  			return []byte(vt.String())
   123  		} else {
   124  			return vt.String()
   125  		}
   126  	}
   127  	return vt.Interface()
   128  }
   129  
   130  func deepEqual(exp interface{}, act interface{}) bool {
   131  	switch ev := exp.(type) {
   132  	case map[int]interface{}:
   133  		av, ok := act.(map[int]interface{})
   134  		if !ok {
   135  			return false
   136  		}
   137  		for k, v := range ev {
   138  			vv, ok := av[k]
   139  			if !ok {
   140  				return false
   141  			}
   142  			if !deepEqual(v, vv) {
   143  				return false
   144  			}
   145  		}
   146  		return true
   147  	case map[string]interface{}:
   148  		av, ok := act.(map[string]interface{})
   149  		if !ok {
   150  			return false
   151  		}
   152  		for k, v := range ev {
   153  			vv, ok := av[k]
   154  			if !ok {
   155  				return false
   156  			}
   157  			if !deepEqual(v, vv) {
   158  				return false
   159  			}
   160  		}
   161  		return true
   162  	case map[interface{}]interface{}:
   163  		av, ok := act.(map[interface{}]interface{})
   164  		if !ok {
   165  			return false
   166  		}
   167  		if len(ev) == 0 {
   168  			return true
   169  		}
   170  		erv := reflect.ValueOf(ev)
   171  		arv := reflect.ValueOf(av)
   172  		eks := erv.MapKeys()
   173  		aks := arv.MapKeys()
   174  		isPointer := eks[0].Elem().Kind() == reflect.Ptr
   175  		if !isPointer {
   176  			for k, v := range ev {
   177  				vv, ok := av[k]
   178  				if !ok {
   179  					return false
   180  				}
   181  				if !deepEqual(v, vv) {
   182  					return false
   183  				}
   184  			}
   185  		} else {
   186  			for _, ek := range eks {
   187  				found := false
   188  				for _, ak := range aks {
   189  					if deepEqual(ek.Elem().Elem().Interface(), ak.Elem().Elem().Interface()) {
   190  						found = true
   191  						evv := erv.MapIndex(ek)
   192  						avv := arv.MapIndex(ak)
   193  						if !deepEqual(evv.Interface(), avv.Interface()) {
   194  							return false
   195  						}
   196  					}
   197  					if !found {
   198  						return false
   199  					}
   200  				}
   201  			}
   202  		}
   203  		return true
   204  	case []interface{}:
   205  		av, ok := act.([]interface{})
   206  		if !ok {
   207  			return false
   208  		}
   209  		for i, v := range ev {
   210  			vv := av[i]
   211  			if !deepEqual(v, vv) {
   212  				return false
   213  			}
   214  		}
   215  		return true
   216  	default:
   217  		return reflect.DeepEqual(exp, act)
   218  	}
   219  }
   220  
   221  func cast(ev interface{}, b bool) interface{} {
   222  	switch ev.(type) {
   223  	case int8:
   224  		if b {
   225  			return byte(ev.(int8))
   226  		}
   227  		return int(ev.(int8))
   228  	case int16:
   229  		return int(ev.(int16))
   230  	case int32:
   231  		return int(ev.(int32))
   232  	case int64:
   233  		return int(ev.(int64))
   234  	case float32:
   235  		return float64(ev.(float32))
   236  	default:
   237  		return ev
   238  	}
   239  }
   240  
   241  
   242  func checkHelper(t *testing.T, exp interface{}, act Value, api string) {
   243  	v := reflect.ValueOf(act)
   244  	f := v.MethodByName(api)
   245  	if f.Kind() != reflect.Func {
   246  		t.Fatalf("method %s not found", api)
   247  	}
   248  	var args []reflect.Value
   249  	if api == "List" || api == "StrMap" || api == "IntMap" || api == "Interface" {
   250  		args = make([]reflect.Value, 1)
   251  		args[0] = reflect.ValueOf(&Options{})
   252  	} else {
   253  		args = make([]reflect.Value, 0)
   254  	}
   255  	rets := f.Call(args)
   256  	if len(rets) != 2 {
   257  		t.Fatal("wrong number of return values")
   258  	}
   259  	require.Nil(t, rets[1].Interface())
   260  	switch api {
   261  	case "List":
   262  		vs := rets[0]
   263  		if vs.Kind() != reflect.Slice {
   264  			t.Fatal("wrong type")
   265  		}
   266  		es := reflect.ValueOf(exp)
   267  		if es.Kind() != reflect.Slice {
   268  			t.Fatal("wrong type")
   269  		}
   270  		for i := 0; i < vs.Len(); i++ {
   271  			vv := vs.Index(i)
   272  			require.Equal(t, cast(es.Index(i).Interface(), vv.Type().Name() == "byte"), vv.Interface())
   273  		}
   274  	case "StrMap":
   275  		vs := rets[0]
   276  		if vs.Kind() != reflect.Map {
   277  			t.Fatal("wrong type")
   278  		}
   279  		es := reflect.ValueOf(exp)
   280  		if es.Kind() != reflect.Map {
   281  			t.Fatal("wrong type")
   282  		}
   283  		ks := vs.MapKeys()
   284  		for i := 0; i < len(ks); i++ {
   285  			vv := vs.MapIndex(ks[i])
   286  			require.Equal(t, cast(es.MapIndex(ks[i]).Interface(), vv.Type().Name() == "byte"), vv.Interface())
   287  		}
   288  	default:
   289  		require.Equal(t, exp, rets[0].Interface())
   290  	}
   291  }
   292  
   293  func testDeepEqual(t *testing.T) {
   294  	a := map[interface{}]interface{}{
   295  		float64(0.1): "A",
   296  		float64(0.2): "B",
   297  		float64(0.3): "C",
   298  		float64(0.4): "D",
   299  		float64(0.5): "E",
   300  		float64(0.6): "F",
   301  		float64(0.7): "G",
   302  		float64(0.8): "H",
   303  		float64(0.9): "I",
   304  	}
   305  	b := map[interface{}]interface{}{
   306  		float64(0.4): "D",
   307  		float64(0.8): "H",
   308  		float64(0.7): "G",
   309  		float64(0.5): "E",
   310  		float64(0.6): "F",
   311  		float64(0.9): "I",
   312  		float64(0.2): "B",
   313  		float64(0.1): "A",
   314  		float64(0.3): "C",
   315  	}
   316  	for i := 0; i < 10; i++ {
   317  		require.Equal(t, a, b)
   318  	}
   319  	require.True(t, deepEqual(a, b))
   320  }
   321  
   322  func structToMapStringInterface(data interface{}) map[string]interface{} {
   323      result := make(map[string]interface{})
   324      valueType := reflect.TypeOf(data)
   325      value := reflect.ValueOf(data)
   326  
   327      for i := 0; i < valueType.NumField(); i++ {
   328          field := valueType.Field(i)
   329          fieldName := field.Name
   330  		if fieldName == "state" || fieldName == "unknownFields" || fieldName == "sizeCache" {
   331  			continue
   332  		}
   333          fieldValue := value.FieldByName(fieldName).Interface()
   334          result[fieldName] = fieldValue
   335      }
   336  
   337      return result
   338  }
   339  
   340  
   341  func structToMapFieldNumberInterface(data interface{}, desc *proto.MessageDescriptor) map[proto.FieldNumber]interface{} {
   342  	result := make(map[proto.FieldNumber]interface{})
   343  	valueType := reflect.TypeOf(data)
   344  	value := reflect.ValueOf(data)
   345  
   346  	for i := 0; i < valueType.NumField(); i++ {
   347  		field := valueType.Field(i)
   348  		fieldName := field.Name
   349  		if fieldName == "state" || fieldName == "unknownFields" || fieldName == "sizeCache" {
   350  			continue
   351  		}
   352  		fieldValue := value.FieldByName(fieldName).Interface()
   353  
   354  		// Convert the field name to FieldNumber type
   355  		fieldNumber := desc.ByName(fieldName).Number()
   356  
   357  		result[fieldNumber] = fieldValue
   358  	}
   359  
   360  	return result
   361  }
   362  
   363  
   364  
   365  
   366  
   367  
   368