You can use some custom struct tags to filter out what you need into a map before marshaling to json. Using pointers for this can get messy fast besides being prone to bugs if each value is not carefully dereferenced.
I would recommend refactoring the simplified example to include a MapOptions struct that handles getting the tag for each available option so you can quickly enumerate and update all available map options instead of hard-coding the tag name as shown.
package main
import (
"encoding/json"
"fmt"
"github.com/fatih/structs"
)
func main() {
myStruct := MyStruct{
Code: 500,
Flags: 10,
OptionField: 0,
}
json, _ := myStruct.ToJson("omitoptions")
fmt.Printf("%s\n", json) // {"Code":500,"Flags":10}
json, _ = myStruct.ToJson("omitempty")
fmt.Printf("%s\n", json) // {"Code":500,"Flags":10}
// entering an invalid tag, or no tag at all, defaults to "structs"
json, _ = myStruct.ToJson("")
fmt.Printf("%s\n", json) // {"Code":500,"Flags":10,"OptionField":0}
}
type MyStruct struct {
Code int `structs:"Code" omitoptions:"Code" omitempty:"Code,omitempty"`
Flags uint8 `structs:"Flags" omitoptions:"Flags" omitempty:"Flags,omitempty"`
OptionField int `structs:"OptionField" omitoptions:"-" omitempty:"OptionField,omitempty"`
}
// ToMap converts the struct to a map, using the selected tag name to filter fields
func (c *MyStruct) ToMap(tag string) map[string]interface{} {
s := structs.New(c)
s.TagName = tag
return s.Map()
}
// ToJson serializes the struct to a JSON byte slice, using the selected tag name
func (c *MyStruct) ToJson(tag string) ([]byte, error) {
m := c.ToMap(tag)
bytes, err := json.Marshal(m)
if err != nil {
return nil, err
}
return bytes, nil
}