|
1 | 1 | package visitor |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "encoding/json" |
5 | | - "reflect" |
6 | | - |
| 4 | + "fmt" |
7 | 5 | "github.com/graphql-go/graphql/language/ast" |
8 | 6 | "github.com/graphql-go/graphql/language/typeInfo" |
| 7 | + "reflect" |
9 | 8 | ) |
10 | 9 |
|
11 | 10 | const ( |
@@ -446,14 +445,63 @@ func convertMap(src interface{}) (dest map[string]interface{}, err error) { |
446 | 445 | if src == nil { |
447 | 446 | return |
448 | 447 | } |
449 | | - var bts []byte |
450 | | - if bts, err = json.Marshal(src); err != nil { |
| 448 | + |
| 449 | + // return if src is already a map |
| 450 | + dest, ok := src.(map[string]interface{}) |
| 451 | + if ok { |
451 | 452 | return |
452 | 453 | } |
453 | | - if err = json.Unmarshal(bts, &dest); err != nil { |
454 | | - return |
| 454 | + |
| 455 | + outputMap := make(map[string]interface{}) |
| 456 | + val := reflect.ValueOf(src) |
| 457 | + |
| 458 | + // Dereference pointer if necessary |
| 459 | + if val.Kind() == reflect.Ptr { |
| 460 | + if val.IsNil() { |
| 461 | + return nil, fmt.Errorf("input is a nil pointer") |
| 462 | + } |
| 463 | + val = val.Elem() |
| 464 | + } |
| 465 | + |
| 466 | + if val.Kind() != reflect.Struct { |
| 467 | + return nil, fmt.Errorf("input is not a struct or pointer to struct") |
455 | 468 | } |
456 | | - return |
| 469 | + |
| 470 | + typ := val.Type() |
| 471 | + for i := 0; i < val.NumField(); i++ { |
| 472 | + field := val.Field(i) |
| 473 | + fieldName := typ.Field(i).Name |
| 474 | + |
| 475 | + switch field.Kind() { |
| 476 | + case reflect.Ptr: |
| 477 | + if field.IsNil() { |
| 478 | + outputMap[fieldName] = nil |
| 479 | + } else { |
| 480 | + nestedMap, err := convertMap(field.Interface()) |
| 481 | + if err != nil { |
| 482 | + return nil, err |
| 483 | + } |
| 484 | + outputMap[fieldName] = nestedMap |
| 485 | + } |
| 486 | + case reflect.Struct: |
| 487 | + nestedMap, err := convertMap(field.Interface()) |
| 488 | + if err != nil { |
| 489 | + return nil, err |
| 490 | + } |
| 491 | + outputMap[fieldName] = nestedMap |
| 492 | + case reflect.Interface: |
| 493 | + if field.IsNil() { |
| 494 | + outputMap[fieldName] = nil |
| 495 | + } else { |
| 496 | + concreteValue := field.Elem() |
| 497 | + outputMap[fieldName], _ = convertMap(concreteValue.Interface()) |
| 498 | + } |
| 499 | + default: |
| 500 | + outputMap[fieldName] = field.Interface() |
| 501 | + } |
| 502 | + } |
| 503 | + |
| 504 | + return outputMap, nil |
457 | 505 | } |
458 | 506 |
|
459 | 507 | // get value by key from struct | slice | map | wrap(prev) |
|
0 commit comments