I'm trying to create a struct based on a response I get. I have no control over the response, and in it's structure there are field names which use comma as part of the filed name itself
JSON Example:
"date": "2022-09-09 00:00:00 UTC",
"Sum": {
"Change, %": "0.10",
"Price": "254",
"Value, $": "455.26",
}
When trying to create a struct the "regular" way, I get an error since once I use the comma character, reflect.StructTag.Get
expects something specific and not the rest of the name.
Struct Example:
Date string `json:"date"`
Sum struct {
Change string `json:"Change, %"`
Price string `json:"Price"`
Value string `json:"Value, $"`
} `json:"Sum"`
The error I receive is:
"struct field tag json:"Value, $"
not compatible with reflect.StructTag.Get: suspicious space in struct tag value"
The goal is to later manipulate and use this data (hopefully using my simple names), so "just" printing the JSON or moving it to an array or similar option cannot be the final step.
The 'Price' field is working as expected, but the problem is with the fields using the comma. I couldn't find a way around it or a similar question.
Would love to understand how to deal with this issue.
Thanks!
CodePudding user response:
You may unmarshal the Sum
JSON object into a Go map, and assign the values from the map to the struct fields. The restriction only applies to struct tags (that they may not contain arbitrary characters like comma), but maps may hold any keys.
For example:
type Sum struct {
Change string
Price string
Value string
}
func (s *Sum) UnmarshalJSON(data []byte) error {
var m map[string]string
if err := json.Unmarshal(data, &m); err != nil {
return err
}
s.Change = m["Change, %"]
s.Price = m["Price"]
s.Value = m["Value, $"]
return nil
}
type model struct {
Date string `json:"date"`
Sum Sum `json:"Sum"`
}
func main() {
var m model
if err := json.Unmarshal([]byte(src), &m); err != nil {
panic(err)
}
fmt.Printf("% v\n", m)
}
const src = `{
"date": "2022-09-09 00:00:00 UTC",
"Sum": {
"Change, %": "0.10",
"Price": "254",
"Value, $": "455.26"
}
}`
This will output (try it on the Go Playground):
{Date:2022-09-09 00:00:00 UTC Sum:{Change:0.10 Price:254 Value:455.26}}