|
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