Question: Modify struct tag and then re-marshal json
brondum opened this issue · 2 comments
brondum commented
Hi.
Is it possible to re-marshal the response after mutating the structtags?
eg.
package main
import (
"encoding/json"
"fmt"
"reflect"
"github.com/fatih/structtag"
)
func main() {
type Payload struct {
Someting string `json:"something"`
}
// get field tag
tag := reflect.TypeOf(Payload{}).Field(0).Tag
// ... and start using structtag by parsing the tag
tags, err := structtag.Parse(string(tag))
if err != nil {
fmt.Printf("error parsing tags: %v", err)
}
fmt.Println(tags)
err = tags.Set(&structtag.Tag{
Key: "json",
Name: "bar",
Options: []string{},
})
if err != nil {
fmt.Println(err)
}
fmt.Println(tags)
payload := Payload{Someting: "woop"}
resp, err := json.Marshal(payload)
if err != nil {
fmt.Printf("error marshaling payload: %v", err)
}
fmt.Printf("%s\n\n", resp)
}
Current response:
json:"something"
json:"bar"
{"something":"woop"}
expected result:
json:"something"
json:"bar"
{"bar":"woop"}
Thank you in advance
fatih commented
This is not part of the library but you can use the reflect
package to achieve it. Here is an example based on your comment: https://play.golang.org/p/YsaqhVHTHJJ
package main
import (
"encoding/json"
"fmt"
"reflect"
"github.com/fatih/structtag"
)
func main() {
type Payload struct {
Someting string `json:"someting"`
}
p := Payload{}
// get field tag
pt := reflect.TypeOf(p)
tag := pt.Field(0).Tag
// ... and start using structtag by parsing the tag
tags, err := structtag.Parse(string(tag))
if err != nil {
fmt.Printf("error parsing tags: %v", err)
}
fmt.Println(tags)
err = tags.Set(&structtag.Tag{
Key: "json",
Name: "bar",
Options: []string{},
})
if err != nil {
fmt.Println(err)
}
fmt.Println(tags)
st := []reflect.StructField{}
for i := 0; i < pt.NumField(); i++ {
st = append(st, pt.Field(i))
}
// replace with our modified tag
st[0].Tag = reflect.StructTag(tags.String())
p2 := reflect.StructOf(st)
v := reflect.ValueOf(p)
v2 := v.Convert(p2)
resp, err := json.Marshal(v2.Interface())
if err != nil {
fmt.Printf("error marshaling payload: %v", err)
}
fmt.Printf("%s\n\n", resp)
}
Closing this as I don't think there is much I can do on my end. Thank you