-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstruct_len.go
51 lines (46 loc) · 1.05 KB
/
struct_len.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package structraw
import (
"fmt"
"reflect"
)
func StructLen(s any) (int, error) {
value := reflect.ValueOf(s)
if reflect.ValueOf(s).Kind() == reflect.Ptr {
value = reflect.Indirect(reflect.ValueOf(s))
}
if value.Kind() != reflect.Struct {
return 0, ErrInvalidType
}
return structLen(value)
}
func structLen(value reflect.Value) (int, error) {
fl := 0
for i := 0; i < value.Type().NumField(); i++ {
field := value.Type().Field(i)
if field.PkgPath != "" {
continue
}
if l, err := fieldLen(field, value.FieldByIndex(field.Index)); err != nil {
return 0, err
} else {
fl += l
}
}
return fl, nil
}
func fieldLen(field reflect.StructField, value reflect.Value) (int, error) {
switch field.Type.Kind() {
case reflect.Uint8:
return 1, nil
case reflect.Uint16:
return 2, nil
case reflect.Uint32:
return 4, nil
case reflect.Uint64:
return 8, nil
case reflect.Array, reflect.Slice:
return value.Len(), nil
default:
return 0, fmt.Errorf("%w: field:%s type kind:%s not support", ErrInvalidType, field.Name, field.Type.Kind())
}
}