Suppose I have the following:
type My struct{
First string `xml:"first"`
Last string `xml:"name"`
...many more tags...
}
I'd like to change the prefix of all the tags to "mycustomtag". I've seen https://stackoverflow.com/a/42549826/522962 but that describes a manual way where you have defined a second struct w/ the tags manually. How do i do so automatically?
e.g. I'd like to end up with something like below but since there are many, many fields how do I do it so I don't have to do it manually?:
// how do I do the next part automagically????
func (m *My) MarshalJSON() ([]byte, error) {
type alias struct {
First string `mycustomtag:"first"`
Last string `mycustomtag:"name"`
...many more tags...
}
var a alias = alias(*m)
return json.Marshal(&a)
}
If this is not at runtime, but statically to modify your code source, you can use fatih/gomodifytags
.
See "Writing a Go Tool to Parse and Modify Struct Tags"
Struct field tags are an important part of encode/decode types, especially when using packages such as encoding/json.
However, modifying tags is repetitive, cumbersome and open to human errors.
We can make it easy to modify tags with an automated tool that is written for this sole purpose.
You also can do it at runtime with reflect if you need.
func (m *My) MarshalJSON() ([]byte, error) {
oldtype := reflect.TypeOf(*m)
fields := make([]reflect.StructField, oldtype.NumField())
for i := 0; i < oldtype.NumField(); i++ {
field := oldtype.Field(i)
if _, ok := field.Tag.Lookup("xml"); ok {
field.Tag = reflect.StructTag(strings.Replace(string(field.Tag), "xml", "json", 1))
}
fields[i] = field
}
newtype := reflect.StructOf(fields)
a := reflect.ValueOf(*m).Convert(newtype).Interface()
return json.Marshal(&a)
}