Home > Blockchain >  Building a struct with a field name which has a comma
Building a struct with a field name which has a comma

Time:09-12

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}}
  • Related