Created
September 28, 2024 16:10
-
-
Save gsitgithub/ecc724eb287bccc52b031504a846ba3a to your computer and use it in GitHub Desktop.
Converting JSON using Generic Wrapper struct for for different types of structs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"reflect" | |
) | |
// NatsMessage with Data field as json.RawMessage | |
type NatsMessage struct { | |
Header string `json:"header"` | |
Data json.RawMessage `json:"data"` | |
} | |
// General function to unmarshal json.RawMessage into a known type | |
func UnmarshalToType(rawData json.RawMessage, target interface{}) error { | |
// Determine the kind of the target type (Map, Slice, or Struct) | |
targetType := reflect.TypeOf(target).Elem().Kind() | |
switch targetType { | |
case reflect.Struct, reflect.Map: | |
// Unmarshal the raw JSON into a map or struct | |
err := json.Unmarshal(rawData, target) | |
if err != nil { | |
return fmt.Errorf("error unmarshalling to target type: %w", err) | |
} | |
case reflect.Slice: | |
// Unmarshal the raw JSON into a slice | |
err := json.Unmarshal(rawData, target) | |
if err != nil { | |
return fmt.Errorf("error unmarshalling slice: %w", err) | |
} | |
default: | |
return fmt.Errorf("unsupported target type: %s", targetType) | |
} | |
return nil | |
} | |
// Example struct for data field | |
type MyCustomData struct { | |
ID int `json:"id"` | |
Value string `json:"value"` | |
} | |
func main() { | |
// Example with a single object | |
jsonData := `{ | |
"header": "example-header", | |
"data": { | |
"id": 123, | |
"value": "hello world" | |
} | |
}` | |
var msg NatsMessage | |
err := json.Unmarshal([]byte(jsonData), &msg) | |
if err != nil { | |
fmt.Println("Error unmarshalling NatsMessage:", err) | |
return | |
} | |
// Unmarshal the Data field to MyCustomData | |
var myData MyCustomData | |
err = UnmarshalToType(msg.Data, &myData) | |
if err != nil { | |
fmt.Println("Error converting data:", err) | |
} else { | |
fmt.Printf("Converted to MyCustomData: %+v\n", myData) | |
} | |
// Example with an array of objects (slice) | |
jsonArrayData := `{ | |
"header": "example-header", | |
"data": [ | |
{ | |
"id": 123, | |
"value": "first entry" | |
}, | |
{ | |
"id": 456, | |
"value": "second entry" | |
} | |
] | |
}` | |
var msgArray NatsMessage | |
err = json.Unmarshal([]byte(jsonArrayData), &msgArray) | |
if err != nil { | |
fmt.Println("Error unmarshalling NatsMessage with array:", err) | |
return | |
} | |
// Unmarshal the Data field into a slice of MyCustomData | |
var myDataArray []MyCustomData | |
err = UnmarshalToType(msgArray.Data, &myDataArray) | |
if err != nil { | |
fmt.Println("Error converting data array:", err) | |
} else { | |
fmt.Printf("Converted to MyCustomData array: %+v\n", myDataArray) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment