github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/goo/goo.go (about) 1 package goo 2 3 import ( 4 "errors" 5 "fmt" 6 "math" 7 "math/bits" 8 "reflect" 9 "runtime" 10 "strconv" 11 "strings" 12 "unicode" 13 ) 14 15 // https://burakkokenn.medium.com/go-goo-c6921cdac348 16 // https://github.com/procyon-projects/goo 17 18 type Exportable interface { 19 IsExported() bool 20 } 21 22 type Invokable interface { 23 Invoke(obj interface{}, args ...interface{}) []interface{} 24 } 25 26 type Member interface { 27 Exportable 28 Name() string 29 String() string 30 } 31 32 type New interface { 33 New() interface{} 34 } 35 36 type Interface interface { 37 Type 38 Methods() []Method 39 MethodNum() int 40 } 41 42 type intType struct { 43 *baseType 44 } 45 46 func newIntType(baseTyp *baseType) intType { return intType{baseType: baseTyp} } 47 48 func (t intType) Methods() []Method { 49 num := t.MethodNum() 50 methods := make([]Method, num) 51 for i := 0; i < num; i++ { 52 methods[i] = ConvertGoMethod(t.typ.Method(i)) 53 } 54 return methods 55 } 56 57 func (t intType) MethodNum() int { return t.typ.NumMethod() } 58 59 type Bool interface { 60 Type 61 New 62 ToBool(value string) bool 63 ToStr(value bool) string 64 } 65 66 type boolType struct { 67 *baseType 68 } 69 70 func newBoolType(baseTyp *baseType) Bool { return boolType{baseType: baseTyp} } 71 72 func (b boolType) ToBool(value string) bool { 73 if value == "true" { 74 return true 75 } else if value == "false" { 76 return false 77 } 78 panic("Given value is not true or false") 79 } 80 81 func (b boolType) ToStr(value bool) string { 82 if value { 83 return "true" 84 } 85 return "false" 86 } 87 88 func (b boolType) New() interface{} { return reflect.New(b.GoType()).Interface() } 89 90 type Array interface { 91 Type 92 New 93 ElemType() Type 94 Len() int 95 } 96 97 type arrayType struct { 98 *baseType 99 elementType Type 100 length int 101 } 102 103 func newArrayType(baseTyp *baseType) Array { 104 return arrayType{ 105 baseType: baseTyp, 106 elementType: FromGoType(baseTyp.GoType().Elem()), 107 length: baseTyp.GoType().Len(), 108 } 109 } 110 111 func (t arrayType) ElemType() Type { return t.elementType } 112 func (t arrayType) Len() int { return t.length } 113 func (t arrayType) New() interface{} { return reflect.New(t.GoType()).Interface() } 114 115 type Field interface { 116 Member 117 Taggable 118 IsAnonymous() bool 119 Type() Type 120 CanSet() bool 121 Set(instance interface{}, value interface{}) 122 Get(instance interface{}) interface{} 123 } 124 125 type field struct { 126 name string 127 typ Type 128 tags reflect.StructTag 129 isAnonymous bool 130 isExported bool 131 index []int 132 } 133 134 func newField(name string, typ Type, isAnonymous, exported bool, tags reflect.StructTag, index []int) field { 135 return field{ 136 name: name, 137 typ: typ, 138 isAnonymous: isAnonymous, 139 tags: tags, 140 isExported: exported, 141 index: index, 142 } 143 } 144 145 func (f field) Name() string { return f.name } 146 func (f field) IsAnonymous() bool { return f.isAnonymous } 147 func (f field) IsExported() bool { return f.isExported } 148 func (f field) CanSet() bool { return f.isExported } 149 func (f field) Type() Type { return f.typ } 150 func (f field) String() string { return f.name } 151 152 func (f field) Tags() (fieldTags []Tag) { 153 tags := f.tags 154 for tags != "" { 155 i := 0 156 for i < len(tags) && tags[i] == ' ' { 157 i++ 158 } 159 tags = tags[i:] 160 if tags == "" { 161 break 162 } 163 164 i = 0 165 for i < len(tags) && tags[i] > ' ' && tags[i] != ':' && tags[i] != '"' && tags[i] != 0x7f { 166 i++ 167 } 168 if i == 0 || i+1 >= len(tags) || tags[i] != ':' || tags[i+1] != '"' { 169 break 170 } 171 name := string(tags[:i]) 172 tags = tags[i+1:] 173 174 i = 1 175 for i < len(tags) && tags[i] != '"' { 176 if tags[i] == '\\' { 177 i++ 178 } 179 i++ 180 } 181 if i >= len(tags) { 182 break 183 } 184 quotedValue := string(tags[:i+1]) 185 tags = tags[i+1:] 186 187 value, err := strconv.Unquote(quotedValue) 188 if err != nil { 189 break 190 } 191 192 fieldTags = append(fieldTags, Tag{Name: name, Value: value}) 193 } 194 return fieldTags 195 } 196 197 func (f field) TagByName(name string) (Tag, error) { 198 if v, ok := f.tags.Lookup(name); ok { 199 return Tag{Name: name, Value: v}, nil 200 } 201 return Tag{}, fmt.Errorf("Tag named %s not found ", name) 202 } 203 204 func (f field) Set(instance interface{}, value interface{}) { 205 if !f.CanSet() { 206 panic("Field cannot be set because of it is an unexported f") 207 } 208 typ := TypeOf(instance) 209 if !typ.IsStruct() { 210 panic("Instance must only be a struct") 211 } 212 if !typ.IsPtr() { 213 panic("Instance type must be a pointer") 214 } 215 v := typ.GoPtrValue().FieldByIndex(f.index) 216 v.Set(reflect.ValueOf(value)) 217 } 218 219 func (f field) Get(instance interface{}) interface{} { 220 typ := TypeOf(instance) 221 if !typ.IsStruct() { 222 panic("Instance must only be a struct") 223 } 224 structType := typ.GoType() 225 structValueType := typ.GoValue() 226 if typ.IsPtr() { 227 structValueType = typ.GoPtrValue() 228 } 229 fieldType := structType.FieldByIndex(f.index) 230 if !IsFieldExported(fieldType) { 231 panic("Field is not exported, you cannot get the value : " + f.name) 232 } 233 234 fv := structValueType.FieldByIndex(f.index) 235 if fieldType.Type.Kind() != reflect.Ptr { 236 return fv.Interface() 237 } 238 239 return fv.Addr().Interface() 240 } 241 242 type Func interface { 243 Type 244 InTypes() []Type 245 InNum() int 246 OutTypes() []Type 247 OutNum() int 248 Call(args []interface{}) []interface{} 249 } 250 251 type funcType struct { 252 *baseType 253 } 254 255 func newFuncType(baseTyp *baseType) funcType { return funcType{baseType: baseTyp} } 256 257 func (t funcType) InTypes() []Type { 258 num := t.InNum() 259 parameterTypes := make([]Type, num) 260 for i := 0; i < num; i++ { 261 parameterTypes[i] = FromGoType(t.typ.In(i)) 262 } 263 return parameterTypes 264 } 265 266 func (t funcType) InNum() int { return t.typ.NumIn() } 267 func (t funcType) OutNum() int { return t.typ.NumOut() } 268 269 func (t funcType) OutTypes() []Type { 270 num := t.OutNum() 271 outTypes := make([]Type, num) 272 for i := 0; i < num; i++ { 273 outTypes[i] = FromGoType(t.typ.Out(i)) 274 } 275 return outTypes 276 } 277 278 func (t funcType) Call(args []interface{}) []interface{} { 279 num := t.InNum() 280 if len(args) != num { 281 panic("Parameter counts don't match argument counts") 282 } 283 284 in := make([]reflect.Value, num) 285 inTypes := t.InTypes() 286 for i, arg := range args { 287 if arg != nil { 288 in[i] = reflect.ValueOf(arg) 289 } else if t := inTypes[i]; t.IsPtr() { 290 in[i] = reflect.New(t.PtrType()).Elem() 291 } else { 292 in[i] = reflect.New(t.GoType()).Elem() 293 } 294 } 295 results := t.val.Call(in) 296 out := make([]interface{}, len(results)) 297 for i, outputParam := range results { 298 out[i] = outputParam.Interface() 299 } 300 return out 301 } 302 303 type Map interface { 304 Type 305 New 306 KeyType() Type 307 ValueType() Type 308 } 309 310 type mapType struct { 311 *baseType 312 keyType Type 313 valueType Type 314 } 315 316 func newMapType(baseTyp *baseType) Map { 317 return mapType{ 318 baseType: baseTyp, 319 keyType: FromGoType(baseTyp.GoType().Key()), 320 valueType: FromGoType(baseTyp.GoType().Elem()), 321 } 322 } 323 324 func (m mapType) KeyType() Type { return m.keyType } 325 func (m mapType) ValueType() Type { return m.valueType } 326 327 func (m mapType) New() interface{} { 328 return reflect.MakeMapWithSize(reflect.MapOf(m.keyType.GoType(), m.valueType.GoType()), 0).Interface() 329 } 330 331 type Method interface { 332 Member 333 Invokable 334 OutNum() int 335 OutTypes() []Type 336 InNum() int 337 InTypes() []Type 338 } 339 340 type method struct { 341 typ reflect.Type 342 name string 343 isExported bool 344 fn reflect.Value 345 index int 346 } 347 348 func newMethod(methodType reflect.Type, name string, exported bool, fn reflect.Value, index int) method { 349 return method{ 350 typ: methodType, 351 name: name, 352 isExported: exported, 353 fn: fn, 354 index: index, 355 } 356 } 357 358 func (m method) Name() string { return m.name } 359 func (m method) IsExported() bool { return m.isExported } 360 func (m method) String() string { return m.name } 361 func (m method) OutNum() int { return m.typ.NumOut() } 362 func (m method) InNum() int { return m.typ.NumIn() } 363 364 func (m method) Invoke(obj interface{}, args ...interface{}) []interface{} { 365 typ := TypeOf(obj) 366 if !typ.IsStruct() { 367 panic("obj must be a struct instance") 368 } 369 370 if num := m.InNum(); len(args) != num-1 { 371 panic("Parameter counts don't match argument counts") 372 } 373 374 args = append([]interface{}{obj}, args[:]...) 375 in := make([]reflect.Value, len(args)) 376 inTypes := m.InTypes() 377 for i, arg := range args { 378 if arg != nil { 379 in[i] = reflect.ValueOf(arg) 380 } else if t := inTypes[i]; t.IsPtr() { 381 in[i] = reflect.New(t.PtrType()).Elem() 382 } else { 383 in[i] = reflect.New(t.GoType()).Elem() 384 } 385 } 386 387 results := typ.GoType().Method(m.index).Func.Call(in) 388 out := make([]interface{}, len(results)) 389 for i, outputParam := range results { 390 out[i] = outputParam.Interface() 391 } 392 return out 393 } 394 395 func (m method) OutTypes() []Type { 396 num := m.OutNum() 397 types := make([]Type, num) 398 for i := 0; i < num; i++ { 399 types[i] = FromGoType(m.typ.Out(i)) 400 } 401 return types 402 } 403 404 func (m method) InTypes() []Type { 405 num := m.InNum() 406 types := make([]Type, num) 407 for i := 0; i < num; i++ { 408 types[i] = FromGoType(m.typ.In(i)) 409 } 410 return types 411 } 412 413 type NumberType int 414 415 const ( 416 IntType NumberType = iota 417 FloatType 418 ComplexType 419 ) 420 421 type BitSize int 422 423 const ( 424 Bit8 BitSize = 8 425 Bit16 BitSize = 16 426 Bit32 BitSize = 32 427 Bit64 BitSize = 64 428 Bit128 BitSize = 128 429 ) 430 431 type Number interface { 432 Type 433 New 434 Type() NumberType 435 BitSize() BitSize 436 Overflow(val interface{}) bool 437 ToString(val interface{}) string 438 } 439 440 type Integer interface { 441 Number 442 IsSigned() bool 443 } 444 445 type signedType struct { 446 *baseType 447 } 448 449 func newSignedType(baseTyp *baseType) signedType { return signedType{baseType: baseTyp} } 450 func (t signedType) Type() NumberType { return IntType } 451 func (t signedType) IsSigned() bool { return true } 452 func (t signedType) New() interface{} { return reflect.New(t.GoType()).Interface() } 453 454 func (t signedType) BitSize() BitSize { 455 switch t.kind { 456 case reflect.Int64: 457 return Bit64 458 case reflect.Int8: 459 return Bit8 460 case reflect.Int16: 461 return Bit16 462 case reflect.Int32: 463 return Bit32 464 default: 465 if bits.UintSize == 32 { 466 return Bit32 467 } 468 return Bit64 469 } 470 } 471 472 func (t signedType) Overflow(val interface{}) bool { 473 valType := TypeOf(val) 474 if !valType.IsNumber() || IntType != valType.(Number).Type() || !valType.(Integer).IsSigned() { 475 panic("Given type is not compatible with signed t") 476 } 477 iv, err := strconv.ParseInt(fmt.Sprintf("%d", val), 10, 64) 478 PanicIf(err) 479 480 s := t.BitSize() 481 return Bit8 == s && (math.MinInt8 > iv || math.MaxInt8 < iv) || 482 Bit16 == s && (math.MinInt16 > iv || math.MaxInt16 < iv) || 483 Bit32 == s && (math.MinInt32 > iv || math.MaxInt32 < iv) 484 } 485 486 func (t signedType) ToString(val interface{}) string { 487 valType := TypeOf(val) 488 if !valType.IsNumber() || IntType != valType.(Number).Type() || !valType.(Integer).IsSigned() { 489 panic("Incompatible type : " + valType.Name()) 490 } 491 return fmt.Sprintf("%d", val) 492 } 493 494 type unsignedType struct { 495 *baseType 496 } 497 498 func newUnsignedType(baseTyp *baseType) unsignedType { return unsignedType{baseType: baseTyp} } 499 func (t unsignedType) Type() NumberType { return IntType } 500 func (t unsignedType) IsSigned() bool { return false } 501 func (t unsignedType) New() interface{} { return reflect.New(t.GoType()).Interface() } 502 503 func (t unsignedType) BitSize() BitSize { 504 switch t.kind { 505 case reflect.Uint64: 506 return Bit64 507 case reflect.Uint8: 508 return Bit8 509 case reflect.Uint16: 510 return Bit16 511 case reflect.Uint32: 512 return Bit32 513 default: 514 if bits.UintSize == 32 { 515 return Bit32 516 } 517 return Bit64 518 } 519 } 520 521 func (t unsignedType) Overflow(val interface{}) bool { 522 valType := TypeOf(val) 523 if !valType.IsNumber() || IntType != valType.(Number).Type() || valType.(Integer).IsSigned() { 524 panic("Given type is not compatible with unsigned t") 525 } 526 v, err := strconv.ParseUint(fmt.Sprintf("%d", val), 10, 64) 527 PanicIf(err) 528 529 size := t.BitSize() 530 return Bit8 == size && math.MaxUint8 < v || 531 Bit16 == size && math.MaxUint16 < v || 532 Bit32 == size && math.MaxUint32 < v 533 } 534 535 func (t unsignedType) ToString(val interface{}) string { 536 typ := TypeOf(val) 537 if !typ.IsNumber() || IntType != typ.(Number).Type() || typ.(Integer).IsSigned() { 538 panic("Incompatible type : " + typ.Name()) 539 } 540 return fmt.Sprintf("%d", val) 541 } 542 543 type Float interface { 544 Number 545 } 546 547 type floatType struct { 548 *baseType 549 } 550 551 func newFloatType(baseTyp *baseType) Float { return floatType{baseType: baseTyp} } 552 553 func (t floatType) New() interface{} { return reflect.New(t.GoType()).Interface() } 554 func (t floatType) Type() NumberType { return FloatType } 555 func (t floatType) BitSize() BitSize { return BitSizeIf(t.kind, reflect.Float32, Bit32, Bit64) } 556 557 func (t floatType) Overflow(val interface{}) bool { 558 if typ := TypeOf(val); !typ.IsNumber() || FloatType != typ.(Number).Type() { 559 panic("Given type is not compatible with t") 560 } 561 v, err := strconv.ParseFloat(fmt.Sprintf("%f", val), 64) 562 PanicIf(err) 563 564 size := t.BitSize() 565 return Bit32 == size && math.MaxFloat32 < v || Bit64 == size && math.MaxFloat64 < v 566 } 567 568 func (t floatType) ToString(val interface{}) string { 569 valType := TypeOf(val) 570 if !valType.IsNumber() || FloatType != valType.(Number).Type() { 571 panic("Incompatible type : " + valType.Name()) 572 } 573 return fmt.Sprintf("%f", val) 574 } 575 576 type Complex interface { 577 Number 578 ImaginaryData(val interface{}) interface{} 579 RealData(val interface{}) interface{} 580 } 581 582 type complexType struct { 583 *baseType 584 } 585 586 func newComplexType(baseTyp *baseType) Complex { return complexType{baseType: baseTyp} } 587 func (t complexType) Type() NumberType { return ComplexType } 588 func (t complexType) Overflow(v interface{}) bool { panic("It does not support Overflow for now") } 589 func (t complexType) BitSize() BitSize { return BitSizeIf(t.kind, reflect.Complex64, Bit64, Bit128) } 590 591 func BitSizeIf(k, ifv reflect.Kind, a, b BitSize) BitSize { 592 if k == ifv { 593 return a 594 } 595 596 return b 597 } 598 599 func (t complexType) ImaginaryData(val interface{}) interface{} { 600 typ := TypeOf(val) 601 if !typ.IsNumber() || ComplexType != typ.(Number).Type() { 602 panic("Given type is not compatible with t") 603 } 604 605 if t.BitSize() == Bit64 { 606 return imag(val.(complex64)) 607 } 608 return imag(val.(complex128)) 609 } 610 611 func (t complexType) RealData(val interface{}) interface{} { 612 typ := TypeOf(val) 613 if !typ.IsNumber() || ComplexType != typ.(Number).Type() { 614 panic("Given type is not compatible with t") 615 } 616 617 if t.BitSize() == Bit64 { 618 return real(val.(complex64)) 619 } 620 return real(val.(complex128)) 621 } 622 623 func (t complexType) New() interface{} { return reflect.New(t.GoType()).Interface() } 624 625 func (t complexType) ToString(val interface{}) string { 626 if typ := TypeOf(val); !typ.IsNumber() || ComplexType != typ.(Number).Type() { 627 panic("Incompatible type : " + typ.Name()) 628 } 629 return fmt.Sprintf("%f", val) 630 } 631 632 type Slice interface { 633 Type 634 New 635 GetElementType() Type 636 } 637 638 type sliceType struct { 639 *baseType 640 elementType Type 641 } 642 643 func newSliceType(baseTyp *baseType) Slice { 644 return sliceType{ 645 baseType: baseTyp, 646 elementType: FromGoType(baseTyp.GoType().Elem()), 647 } 648 } 649 650 func (t sliceType) GetElementType() Type { return t.elementType } 651 652 func (t sliceType) New() interface{} { 653 return reflect.MakeSlice(t.GoType(), t.val.Len(), t.val.Cap()).Interface() 654 } 655 656 type String interface { 657 Type 658 New 659 ToNumber(val string, number Number) (interface{}, error) 660 ToInt(val string) int 661 ToInt8(val string) int8 662 ToInt16(val string) int16 663 ToInt32(val string) int32 664 ToInt64(val string) int64 665 ToUint(val string) uint 666 ToUint8(val string) uint8 667 ToUint16(val string) uint16 668 ToUint32(val string) uint32 669 ToUint64(val string) uint64 670 ToFloat32(val string) float32 671 ToFloat64(val string) float64 672 } 673 674 type stringType struct { 675 *baseType 676 } 677 678 func newStringType(baseTyp *baseType) stringType { 679 return stringType{ 680 baseType: baseTyp, 681 } 682 } 683 684 func (t stringType) ToNumber(val string, number Number) (interface{}, error) { 685 if number == nil { 686 panic("Number must not be null") 687 } 688 689 if numberType := number.Type(); IntType == numberType { 690 return ParseInt(val, number.(Integer)) 691 } else if FloatType == numberType { 692 return getFloatValue(val, number.(Float)) 693 } 694 return nil, errors.New("complex numbers does not support for now") 695 } 696 697 func (t stringType) ToInt(val string) int { 698 var result interface{} 699 if bits.UintSize == 32 { 700 result = parseInt(val, Bit32, true) 701 } else { 702 result = parseInt(val, Bit64, true) 703 } 704 705 if bits.UintSize == 32 { 706 return result.(int) 707 } 708 return int(result.(int64)) 709 } 710 711 func (t stringType) ToInt8(val string) int8 { return parseInt(val, Bit8, true).(int8) } 712 func (t stringType) ToInt16(val string) int16 { return parseInt(val, Bit16, true).(int16) } 713 func (t stringType) ToInt32(val string) int32 { return parseInt(val, Bit32, true).(int32) } 714 func (t stringType) ToInt64(val string) int64 { return parseInt(val, Bit64, true).(int64) } 715 716 func PanicIf(err error) { 717 if err != nil { 718 panic(err) 719 } 720 } 721 722 func (t stringType) ToUint(val string) uint { 723 var result interface{} 724 if bits.UintSize == 32 { 725 result = parseInt(val, Bit32, false) 726 } else { 727 result = parseInt(val, Bit64, false) 728 } 729 730 if bits.UintSize == 32 { 731 return result.(uint) 732 } 733 lastValue := result.(uint64) 734 return uint(lastValue) 735 } 736 737 func (t stringType) ToUint8(val string) uint8 { return parseInt(val, Bit8, false).(uint8) } 738 func (t stringType) ToUint16(val string) uint16 { return parseInt(val, Bit16, false).(uint16) } 739 func (t stringType) ToUint32(val string) uint32 { return parseInt(val, Bit32, false).(uint32) } 740 func (t stringType) ToUint64(val string) uint64 { return parseInt(val, Bit64, false).(uint64) } 741 func (t stringType) ToFloat32(val string) float32 { return float32(ParseFloat(val, int(Bit32))) } 742 func (t stringType) ToFloat64(val string) float64 { return ParseFloat(val, int(Bit64)) } 743 744 func ParseFloat(val string, bitSize int) float64 { 745 v, err := strconv.ParseFloat(val, bitSize) 746 PanicIf(err) 747 return v 748 } 749 750 func ParseInt(s string, typ Integer) (resultValue interface{}, err error) { 751 var value interface{} 752 var signedValue int64 753 var unsignedValue uint64 754 if typ.IsSigned() { 755 signedValue, err = strconv.ParseInt(s, 10, 64) 756 value = signedValue 757 } else { 758 unsignedValue, err = strconv.ParseUint(s, 10, 64) 759 value = unsignedValue 760 } 761 762 if err != nil { 763 return nil, err 764 } 765 766 if typ.Overflow(value) { 767 return nil, errors.New("The given value is out of range of the typ type : " + typ.String()) 768 } 769 770 intVal := reflect.New(typ.GoType()).Elem() 771 if typ.IsSigned() { 772 intVal.SetInt(signedValue) 773 } else { 774 intVal.SetUint(unsignedValue) 775 } 776 resultValue = intVal.Interface() 777 return 778 } 779 780 func parseInt(s string, bitSize BitSize, isSigned bool) (result interface{}) { 781 if Bit128 == bitSize { 782 panic("BitSize does not support 128") 783 } 784 785 var signedValue int64 786 var unsignedValue uint64 787 var err error 788 if isSigned { 789 signedValue, err = strconv.ParseInt(s, 10, 64) 790 } else { 791 unsignedValue, err = strconv.ParseUint(s, 10, 64) 792 } 793 PanicIf(err) 794 795 overflow := false 796 if isSigned { 797 overflow = Bit8 == bitSize && (math.MinInt8 > signedValue || math.MaxInt8 < signedValue) || 798 Bit16 == bitSize && (math.MinInt16 > signedValue || math.MaxInt16 < signedValue) || 799 Bit32 == bitSize && (math.MinInt32 > signedValue || math.MaxInt32 < signedValue) 800 } else { 801 overflow = Bit8 == bitSize && math.MaxUint8 < unsignedValue || 802 Bit16 == bitSize && math.MaxUint16 < unsignedValue || 803 Bit32 == bitSize && math.MaxUint32 < unsignedValue 804 } 805 806 if overflow { 807 panic("the given value is out of range of the integer type") 808 } 809 810 if isSigned { 811 if Bit8 == bitSize { 812 return int8(signedValue) 813 } else if Bit16 == bitSize { 814 return int16(signedValue) 815 } else if Bit32 == bitSize { 816 return int32(signedValue) 817 } 818 return signedValue 819 } 820 821 if Bit8 == bitSize { 822 return uint8(unsignedValue) 823 } else if Bit16 == bitSize { 824 return uint16(unsignedValue) 825 } else if Bit32 == bitSize { 826 return uint32(unsignedValue) 827 } 828 return unsignedValue 829 } 830 831 func getFloatValue(strValue string, float Float) (resultValue interface{}, err error) { 832 var value float64 833 value, err = strconv.ParseFloat(strValue, 64) 834 if err != nil { 835 return nil, err 836 } 837 838 if float.Overflow(value) { 839 return nil, errors.New("The given value is out of range of the float type : " + float.String()) 840 } 841 floatValue := reflect.New(float.GoType()).Elem() 842 floatValue.SetFloat(value) 843 resultValue = floatValue.Interface() 844 return 845 } 846 847 func (t stringType) New() interface{} { return reflect.New(t.GoType()).Interface() } 848 849 type Struct interface { 850 Type 851 New 852 Fields() []Field 853 FieldNum() int 854 FieldsExported() []Field 855 FieldExportedNum() int 856 FieldsUnexported() []Field 857 FieldUnexportedNum() int 858 FieldsAnonymous() []Field 859 FieldAnonymousNum() int 860 Methods() []Method 861 MethodNum() int 862 Implements(i Interface) bool 863 IsEmbedded(candidate Struct) bool 864 } 865 866 type structType struct { 867 *baseType 868 } 869 870 func newStructType(baseTyp *baseType) structType { 871 return structType{ 872 baseType: baseTyp, 873 } 874 } 875 876 func (t structType) Fields() []Field { 877 num := t.FieldNum() 878 fields := make([]Field, num) 879 for i := 0; i < num; i++ { 880 fields[i] = ConvertGoField(t.typ.Field(i)) 881 } 882 return fields 883 } 884 885 func (t structType) FieldNum() int { return t.typ.NumField() } 886 887 func (t structType) FieldsExported() []Field { 888 return t.FieldsIf(func(f Field) bool { return f.IsExported() }) 889 } 890 891 func (t structType) FieldExportedNum() int { 892 return t.NumIf(func(f Field) bool { return f.IsExported() }) 893 } 894 895 func (t structType) FieldsUnexported() []Field { 896 return t.FieldsIf(func(f Field) bool { return !f.IsExported() }) 897 } 898 899 func (t structType) FieldUnexportedNum() int { 900 return t.NumIf(func(f Field) bool { return !f.IsExported() }) 901 } 902 903 func (t structType) FieldsAnonymous() []Field { 904 return t.FieldsIf(func(f Field) bool { return f.IsAnonymous() }) 905 } 906 907 func (t structType) FieldAnonymousNum() int { 908 return t.NumIf(func(f Field) bool { return f.IsAnonymous() }) 909 } 910 911 func (t structType) FieldsIf(predicate func(Field) bool) (fields []Field) { 912 for _, field := range t.Fields() { 913 if predicate(field) { 914 fields = append(fields, field) 915 } 916 } 917 return fields 918 } 919 920 func (t structType) NumIf(predicate func(Field) bool) (n int) { 921 for _, field := range t.Fields() { 922 if predicate(field) { 923 n++ 924 } 925 } 926 return n 927 } 928 929 func (t structType) Methods() (methods []Method) { 930 for i := 0; i < t.MethodNum(); i++ { 931 var method reflect.Method 932 if t.isPtr { 933 method = t.ptrType.Method(i) 934 } else { 935 method = t.typ.Method(i) 936 } 937 methods = append(methods, ConvertGoMethod(method)) 938 } 939 return methods 940 } 941 942 func (t structType) MethodNum() int { 943 if t.isPtr { 944 return t.ptrType.NumMethod() 945 } 946 return t.typ.NumMethod() 947 } 948 949 func (t structType) Implements(i Interface) bool { 950 if t.isPtr { 951 return t.PtrType().Implements(i.GoType()) 952 } 953 return t.GoType().Implements(i.GoType()) 954 } 955 956 func (t structType) New() interface{} { return reflect.New(t.GoType()).Interface() } 957 958 func (t structType) IsEmbedded(candidate Struct) bool { 959 if candidate == nil { 960 panic("candidate must not be null") 961 } 962 return t.embeddedStruct(t, candidate) 963 } 964 965 func (t structType) embeddedStruct(parent Struct, candidate Struct) bool { 966 for _, f := range parent.Fields() { 967 if f.IsAnonymous() && f.Type().IsStruct() { 968 if candidate.Equals(f.Type()) { 969 return true 970 } 971 if f.Type().(Struct).FieldNum() > 0 { 972 return t.embeddedStruct(f.Type().(Struct), candidate) 973 } 974 } 975 } 976 return false 977 } 978 979 type Tag struct { 980 Name string 981 Value string 982 } 983 984 func (t Tag) String() string { return t.Name + "->" + t.Value } 985 986 type Taggable interface { 987 Tags() []Tag 988 TagByName(name string) (Tag, error) 989 } 990 991 type TypeConverter interface { 992 IsBool() bool 993 ToBoolType() Bool 994 IsNumber() bool 995 ToNumberType() Number 996 IsFunc() bool 997 ToFuncType() Func 998 IsStruct() bool 999 ToStructType() Struct 1000 IsInterface() bool 1001 ToInterfaceType() Interface 1002 IsString() bool 1003 ToStringType() String 1004 IsMap() bool 1005 ToMapType() Map 1006 IsArray() bool 1007 ToArrayType() Array 1008 IsSlice() bool 1009 ToSliceType() Slice 1010 } 1011 1012 type Type interface { 1013 TypeConverter 1014 Name() string 1015 NameFull() string 1016 PkgName() string 1017 PkgNameFull() string 1018 PtrType() reflect.Type 1019 GoPtrValue() reflect.Value 1020 GoType() reflect.Type 1021 GoValue() reflect.Value 1022 IsPtr() bool 1023 IsInstantiable() bool 1024 String() string 1025 Equals(anotherType Type) bool 1026 } 1027 1028 type baseType struct { 1029 parentType interface{} 1030 name string 1031 pkgName string 1032 pkgFullName string 1033 typ reflect.Type 1034 val reflect.Value 1035 ptrType reflect.Type 1036 ptrVal reflect.Value 1037 kind reflect.Kind 1038 isNumber bool 1039 isPtr bool 1040 } 1041 1042 func newBaseType(typ reflect.Type, val reflect.Value) *baseType { 1043 return &baseType{ 1044 name: getTypeName(typ, val), 1045 pkgName: getPkgName(typ, val), 1046 pkgFullName: getPkgFullName(typ, val), 1047 typ: typ, 1048 val: val, 1049 kind: typ.Kind(), 1050 isNumber: IsNumber(typ), 1051 } 1052 } 1053 1054 func (t baseType) NameFull() string { 1055 if t.pkgFullName == "" { 1056 return t.name 1057 } 1058 return t.pkgFullName + "." + t.name 1059 } 1060 func (t baseType) Name() string { return t.name } 1061 func (t baseType) PkgName() string { return t.pkgName } 1062 func (t baseType) PkgNameFull() string { return t.pkgFullName } 1063 func (t baseType) PtrType() reflect.Type { return t.ptrType } 1064 func (t baseType) GoPtrValue() reflect.Value { return t.ptrVal } 1065 func (t baseType) GoType() reflect.Type { return t.typ } 1066 func (t baseType) GoValue() reflect.Value { return t.val } 1067 func (t baseType) IsBool() bool { return reflect.Bool == t.kind } 1068 func (t baseType) IsNumber() bool { return t.isNumber } 1069 func (t baseType) IsFunc() bool { return reflect.Func == t.kind } 1070 func (t baseType) IsStruct() bool { return reflect.Struct == t.kind } 1071 func (t baseType) IsInterface() bool { return reflect.Interface == t.kind } 1072 func (t baseType) IsString() bool { return reflect.String == t.kind } 1073 func (t baseType) IsMap() bool { return reflect.Map == t.kind } 1074 func (t baseType) IsArray() bool { return reflect.Array == t.kind } 1075 func (t baseType) IsSlice() bool { return reflect.Slice == t.kind } 1076 func (t baseType) IsPtr() bool { return t.isPtr } 1077 func (t baseType) IsInstantiable() bool { return !(t.IsInterface() || t.IsFunc()) } 1078 func (t baseType) ToBoolType() Bool { return t.parentType.(Bool) } 1079 func (t baseType) ToNumberType() Number { return t.parentType.(Number) } 1080 func (t baseType) ToFuncType() Func { return t.parentType.(Func) } 1081 func (t baseType) ToInterfaceType() Interface { return t.parentType.(Interface) } 1082 func (t baseType) ToStringType() String { return t.parentType.(String) } 1083 func (t baseType) ToMapType() Map { return t.parentType.(Map) } 1084 func (t baseType) ToArrayType() Array { return t.parentType.(Array) } 1085 func (t baseType) ToSliceType() Slice { return t.parentType.(Slice) } 1086 func (t baseType) ToStructType() Struct { return t.parentType.(Struct) } 1087 func (t baseType) String() string { return t.name } 1088 func (t baseType) Equals(that Type) bool { return that != nil && t.typ == that.GoType() } 1089 1090 func TypeOf(obj interface{}) Type { 1091 typ, val, isPtr := GoTypeAndValue(obj) 1092 baseTyp := newBaseType(typ, val) 1093 populatePtrInfo(obj, baseTyp, isPtr) 1094 actualType := getActualTypeFromBaseType(baseTyp) 1095 baseTyp.parentType = actualType 1096 return actualType 1097 } 1098 1099 func populatePtrInfo(obj interface{}, baseType *baseType, isPtr bool) { 1100 if isPtr { 1101 typ, val := GoPtrTypeAndValue(obj) 1102 baseType.isPtr = true 1103 baseType.ptrType = typ 1104 baseType.ptrVal = val 1105 } 1106 } 1107 1108 func FromGoType(typ reflect.Type) Type { 1109 if typ == nil { 1110 panic("Type cannot be nil") 1111 } 1112 var ptrType reflect.Type 1113 isPtr := typ.Kind() == reflect.Ptr 1114 if isPtr { 1115 ptrType = typ 1116 typ = typ.Elem() 1117 } 1118 baseTyp := newBaseType(typ, reflect.Value{}) 1119 actualType := getActualTypeFromBaseType(baseTyp) 1120 baseTyp.parentType = actualType 1121 if isPtr { 1122 baseTyp.ptrType = ptrType 1123 baseTyp.isPtr = true 1124 } 1125 return actualType 1126 } 1127 1128 func sanitizedName(str string) string { 1129 n := strings.ReplaceAll(str, "/", ".") 1130 n = strings.ReplaceAll(n, "-", ".") 1131 return strings.ReplaceAll(n, "_", ".") 1132 } 1133 1134 func getActualTypeFromBaseType(b *baseType) Type { 1135 switch { 1136 case b.IsFunc(): 1137 return newFuncType(b) 1138 case b.IsInterface(): 1139 return newIntType(b) 1140 case b.IsStruct(): 1141 return newStructType(b) 1142 case b.IsNumber(): 1143 switch { 1144 case IsSigned(b.typ): 1145 return newSignedType(b) 1146 case IsUnsigned(b.typ): 1147 return newUnsignedType(b) 1148 case IsFloat(b.typ): 1149 return newFloatType(b) 1150 case IsComplex(b.typ): 1151 return newComplexType(b) 1152 } 1153 case b.IsString(): 1154 return newStringType(b) 1155 case b.IsBool(): 1156 return newBoolType(b) 1157 case b.IsMap(): 1158 return newMapType(b) 1159 case b.IsArray(): 1160 return newArrayType(b) 1161 case b.IsSlice(): 1162 return newSliceType(b) 1163 } 1164 panic(b.Name() + " isn't supported for now") 1165 } 1166 1167 func getTypeName(typ reflect.Type, val reflect.Value) string { 1168 defer func() { recover() }() 1169 switch typ.Kind() { 1170 case reflect.Struct, reflect.Interface: 1171 return GoTypeName(typ) 1172 case reflect.Func: 1173 return GoFuncName(val) 1174 } 1175 return typ.Name() 1176 } 1177 1178 func GoTypeAndValue(obj interface{}) (reflect.Type, reflect.Value, bool) { 1179 typ := reflect.TypeOf(obj) 1180 if typ == nil { 1181 panic("Type cannot be determined as the given object is nil") 1182 } 1183 isPtr := typ.Kind() == reflect.Ptr 1184 if isPtr { 1185 typ = typ.Elem() 1186 } 1187 val := reflect.ValueOf(obj) 1188 if val.Kind() == reflect.Ptr { 1189 val = val.Elem() 1190 } 1191 1192 return typ, val, isPtr 1193 } 1194 1195 func GoPtrTypeAndValue(obj interface{}) (reflect.Type, reflect.Value) { 1196 typ := reflect.TypeOf(obj) 1197 if typ == nil { 1198 panic("Type cannot be determined as the given object is nil") 1199 } 1200 1201 var ptrType reflect.Type 1202 var ptrVal reflect.Value 1203 if typ.Kind() == reflect.Ptr { 1204 ptrType = typ 1205 ptrVal = reflect.ValueOf(obj).Elem() 1206 } 1207 1208 return ptrType, ptrVal 1209 } 1210 1211 func GoTypeName(typ reflect.Type) string { 1212 name := typ.Name() 1213 if name != "" { 1214 return name 1215 } 1216 return typ.String() 1217 } 1218 1219 func getPkgName(typ reflect.Type, val reflect.Value) string { 1220 defer func() { recover() }() 1221 1222 if reflect.Func == typ.Kind() { 1223 return FuncPkgName(val) 1224 } 1225 if i := strings.LastIndex(typ.String(), "."); i >= 0 { 1226 return typ.String()[:i] 1227 } 1228 return "" 1229 } 1230 1231 func getPkgFullName(typ reflect.Type, val reflect.Value) string { 1232 defer func() { recover() }() 1233 1234 if reflect.Func == typ.Kind() { 1235 return FuncPkgFullName(val) 1236 } 1237 return sanitizedName(typ.PkgPath()) 1238 } 1239 1240 func GoFuncName(val reflect.Value) string { 1241 fullName := runtime.FuncForPC(val.Pointer()).Name() 1242 if pos := strings.LastIndex(fullName, "."); pos < 0 { 1243 return fullName[pos+1:] 1244 } 1245 return fullName 1246 } 1247 1248 func FuncPkgFullName(val reflect.Value) string { 1249 fullName := runtime.FuncForPC(val.Pointer()).Name() 1250 if pos := strings.LastIndex(fullName, "."); pos < 0 { 1251 return fullName[:pos] 1252 } 1253 return sanitizedName(fullName) 1254 } 1255 1256 func FuncPkgName(val reflect.Value) string { 1257 fullName := FuncPkgFullName(val) 1258 if pos := strings.LastIndex(fullName, "."); pos < 0 { 1259 return fullName[pos+1:] 1260 } 1261 return fullName 1262 } 1263 1264 func ConvertGoField(f reflect.StructField) Field { 1265 return newField(f.Name, FromGoType(f.Type), f.Anonymous, IsFieldExported(f), f.Tag, f.Index) 1266 } 1267 1268 func IsFieldExported(f reflect.StructField) bool { return unicode.IsUpper(rune(f.Name[0])) } 1269 func IsMethodExported(m reflect.Method) bool { return unicode.IsUpper(rune(m.Name[0])) } 1270 1271 func ConvertGoMethod(m reflect.Method) Method { 1272 return newMethod(m.Type, m.Name, IsMethodExported(m), m.Func, m.Index) 1273 } 1274 1275 func IsNumber(typ reflect.Type) bool { 1276 return IsAnyKind(typ, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1277 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 1278 reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128) 1279 } 1280 1281 func IsSigned(typ reflect.Type) bool { 1282 return IsAnyKind(typ, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64) 1283 } 1284 1285 func IsUnsigned(typ reflect.Type) bool { 1286 return IsAnyKind(typ, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64) 1287 } 1288 func IsFloat(typ reflect.Type) bool { return IsAnyKind(typ, reflect.Float32, reflect.Float64) } 1289 func IsComplex(typ reflect.Type) bool { return IsAnyKind(typ, reflect.Complex64, reflect.Complex128) } 1290 1291 func IsAnyKind(typ reflect.Type, kinds ...reflect.Kind) bool { 1292 kind := typ.Kind() 1293 for _, k := range kinds { 1294 if kind == k { 1295 return true 1296 } 1297 } 1298 1299 return false 1300 }