Skip to content

Instantly share code, notes, and snippets.

@gsitgithub
Created September 28, 2024 16:10
Show Gist options
  • Save gsitgithub/ecc724eb287bccc52b031504a846ba3a to your computer and use it in GitHub Desktop.
Save gsitgithub/ecc724eb287bccc52b031504a846ba3a to your computer and use it in GitHub Desktop.
Converting JSON using Generic Wrapper struct for for different types of structs
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