github.com/haraldrudell/parl@v0.4.176/preflect/predeclared-type.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 // Package preflect obtains underlying type using reflection 7 package preflect 8 9 import ( 10 "reflect" 11 "strconv" 12 "strings" 13 "unsafe" 14 ) 15 16 const ( 17 Nil = "nil" 18 kindInt = "int" 19 kindUint = "uint" 20 ) 21 22 // bitSize is a string containing the size of int: "(64)" 23 var bitSize = "(" + strconv.Itoa(int(unsafe.Sizeof(0)*8)) + ")" 24 25 // PredeclaredType returns a string describing the underlying type of value 26 // - examples: "bool" "uint8" "int(64)" 27 // - no named types or type aliases 28 func PredeclaredType(value any) (s string) { 29 return reflectTypeString(reflect.TypeOf(value)) 30 } 31 32 func reflectTypeString(typeOf reflect.Type) (s string) { 33 if typeOf == nil { 34 return Nil 35 } 36 var kindOf reflect.Kind = typeOf.Kind() 37 switch kindOf { 38 case reflect.Chan: 39 var chanDir reflect.ChanDir = typeOf.ChanDir() 40 return chanDir.String() + " " + reflectTypeString(typeOf.Elem()) 41 case reflect.Map: 42 return "[" + reflectTypeString(typeOf.Key()) + "]" + reflectTypeString(typeOf.Elem()) 43 case reflect.Interface: 44 return "interface " + reflectTypeString(typeOf.Elem()) 45 case reflect.Func: 46 var sIn, sOut string 47 if in := typeOf.NumIn(); in != 0 { 48 sInList := make([]string, in) 49 for i := range sInList { 50 sInList[i] = reflectTypeString(typeOf.In(i)) 51 } 52 sIn = "(" + strings.Join(sInList, ", ") + ")" 53 } else { 54 sIn = "()" 55 } 56 if out := typeOf.NumOut(); out != 0 { 57 sOutList := make([]string, out) 58 for i := range sOutList { 59 sOutList[i] = reflectTypeString(typeOf.Out(i)) 60 } 61 sOut = " (" + strings.Join(sOutList, ", ") + ")" 62 } 63 return kindOf.String() + sIn + sOut 64 case reflect.Ptr: 65 return "*" + reflectTypeString(typeOf.Elem()) 66 case reflect.Struct: 67 var fields string 68 if numFields := typeOf.NumField(); numFields > 0 { 69 var sList = make([]string, numFields) 70 for i := range sList { 71 var structField reflect.StructField = typeOf.FieldByIndex([]int{i}) 72 sList[i] = reflectTypeString(structField.Type) 73 } 74 fields = strings.Join(sList, "; ") + " " 75 } 76 return "struct{ " + fields + "}" 77 case reflect.Slice: 78 return "[]" + reflectTypeString(typeOf.Elem()) 79 case reflect.Array: 80 return "[" + strconv.Itoa(typeOf.Len()) + "]" + reflectTypeString(typeOf.Elem()) 81 case reflect.Int, reflect.Uint: 82 return kindOf.String() + bitSize // "int(64)" 83 default: 84 return kindOf.String() 85 } 86 }