Skip to content

Instantly share code, notes, and snippets.

@santiaago
Last active December 11, 2020 12:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save santiaago/8669270 to your computer and use it in GitHub Desktop.
Save santiaago/8669270 to your computer and use it in GitHub Desktop.
json Marshal omitempty examples
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type T1 struct {
Field1 string
Field2 string
IsSomething bool
}
type T2 struct {
Field1 *string `json:",omitempty"`
Field2 *string `json:",omitempty"`
IsSomething *bool `json:",omitempty"`
}
type T3 struct {
Field1T3 *string `json:",omitempty"`
Field2T3 *string `json:",omitempty"`
IsSomethingT3 *bool `json:",omitempty"`
IsSomethingElseT3 *bool `json:",omitempty"`
}
func CopyToPtrBasedStructGeneric(tSrc interface{}, tDest interface{}) {
s1 := reflect.ValueOf(tSrc).Elem()
s2 := reflect.ValueOf(tDest).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
s2.Field(i).Set(f1.Addr())
}
}
}
func (t *T2) Copy(tToCopy T1) {
s1 := reflect.ValueOf(&tToCopy).Elem()
s2 := reflect.ValueOf(t).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
s2.Field(i).Set(f1.Addr())
}
}
}
func CopyToPtrBasedStruct(tToCopy T1, t *T2) {
s1 := reflect.ValueOf(&tToCopy).Elem()
s2 := reflect.ValueOf(t).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
s2.Field(i).Set(f1.Addr())
}
}
}
func main() {
var a T1
a.Field1 = "foo"
a.Field2 = "bar"
a.IsSomething = false
res, _ := json.Marshal(a)
fmt.Printf("Original:\n %s\n\n", res)
var b T2
b.Copy(a)
res, _ = json.Marshal(b)
fmt.Printf("Copy Method:\n %s\n\n", res)
var c T2
CopyToPtrBasedStruct(a, &c)
res, _ = json.Marshal(c)
fmt.Printf("Copy to pointer based structure:\n %s\n\n", res)
var d T3
CopyToPtrBasedStructGeneric(&a, &d)
res, _ = json.Marshal(c)
fmt.Printf("Copy to pointer based structure generic:\n %s\n\n", res)
//Original:
//{"Field1":"foo","Field2":"bar","IsSomething":false}
//
//Copy Method:
// {"Field1":"foo","Field2":"bar","IsSomething":false}
//
//Copy to pointer based structure:
// {"Field1":"foo","Field2":"bar","IsSomething":false}
//
//Copy to pointer based structure generic:
// {"Field1":"foo","Field2":"bar","IsSomething":false}
}
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type TA struct {
Field1 string
Field2 string
IsSomething bool
}
type TB struct {
Field1 *string `json:",omitempty"`
Field2 *string `json:",omitempty"`
IsSomething *bool `json:",omitempty"`
}
type arrayOfStrings []string
func (a arrayOfStrings) Contains(s string) bool {
for _, e := range a {
if e == s {
return true
}
}
return false
}
func InitPointerStructure(pSrc interface{}, pDest interface{}, fieldsToKeep arrayOfStrings) {
s1 := reflect.ValueOf(pSrc).Elem()
s2 := reflect.ValueOf(pDest).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
if fieldsToKeep.Contains(s2.Type().Field(i).Name) {
s2.Field(i).Set(f1.Addr())
} else {
s2.Field(i).Set(reflect.Zero(s2.Type().Field(i).Type))
}
}
}
}
func InitArrayOfPointerStructure(pArraySrc interface{}, pArrayDest interface{}, fieldsToKeep arrayOfStrings) {
arraySrc := reflect.ValueOf(pArraySrc).Elem()
arrayDest := reflect.ValueOf(pArrayDest).Elem()
for i := 0; i < arraySrc.Len(); i++ {
src := arraySrc.Index(i)
dest := arrayDest.Index(i)
for j := 0; j < src.NumField(); j++ {
srcField := src.Field(j)
destField := dest.Field(j)
if destField.CanSet() {
if fieldsToKeep.Contains(dest.Type().Field(j).Name) {
destField.Set(srcField.Addr())
} else {
destField.Set(reflect.Zero(dest.Type().Field(j).Type))
}
}
}
}
}
func main() {
var a1 TA
var a2 TA
a1.Field1 = "foo"
a1.Field2 = "bar"
a1.IsSomething = false
a2.Field1 = "foo2"
a2.Field2 = "bar2"
a2.IsSomething = true
tableA := make([]TA, 2)
tableA[0] = a1
tableA[1] = a2
tableB := make([]TB, len(tableA))
toKeep := []string{"Field2"}
InitArrayOfPointerStructure(&tableA, &tableB, toKeep)
for _, a := range tableA {
resA, _ := json.Marshal(a)
fmt.Printf("A: %s\n", resA)
}
for _, b := range tableB {
resB, _ := json.Marshal(b)
fmt.Printf("B: %s\n", resB)
}
// A: {"Field1":"foo","Field2":"bar","IsSomething":false}
// A: {"Field1":"foo2","Field2":"bar2","IsSomething":true}
// B: {"Field2":"bar"}
// B: {"Field2":"bar2"}
}
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type TA struct {
Field1 string
Field2 string
IsSomething bool
}
type TB struct {
Field1 *string `json:",omitempty"`
Field2 *string `json:",omitempty"`
IsSomething *bool `json:",omitempty"`
}
type arrayOfStrings []string
func (a arrayOfStrings) Contains(s string) bool {
for _, e := range a {
if e == s {
return true
}
}
return false
}
func InitPointerStructure(pSrc interface{}, pDest interface{}, fieldsToKeep arrayOfStrings) {
s1 := reflect.ValueOf(pSrc).Elem()
s2 := reflect.ValueOf(pDest).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
if fieldsToKeep.Contains(s2.Type().Field(i).Name) {
s2.Field(i).Set(f1.Addr())
} else {
s2.Field(i).Set(reflect.Zero(s2.Type().Field(i).Type))
}
}
}
}
func main() {
var a TA
a.Field1 = "foo"
a.Field2 = "bar"
a.IsSomething = false
var b TB
toKeep := []string{"Field2"}
InitPointerStructure(&a, &b, toKeep)
resA, _ := json.Marshal(a)
fmt.Printf("A: %s\n", resA)
resB, _ := json.Marshal(b)
fmt.Printf("B: %s\n", resB)
// A: {"Field1":"foo","Field2":"bar","IsSomething":false}
// B: {"Field2":"bar"}
}
package main
import (
"fmt"
"reflect"
"encoding/json"
)
type TA struct {
Field1 string
Field2 string
IsSomething bool
}
type TB struct {
Field1 *string `json:",omitempty"`
Field2 *string `json:",omitempty"`
IsSomething *bool `json:",omitempty"`
}
type arrayOfStrings []string
func (a arrayOfStrings) Contains(s string) bool {
for _, e := range a {
if e == s {
return true
}
}
return false
}
func CopyToPointerStructure(tSrc interface{}, tDest interface{}) {
s1 := reflect.ValueOf(tSrc).Elem()
s2 := reflect.ValueOf(tDest).Elem()
for i := 0; i < s1.NumField(); i++ {
f1 := s1.Field(i)
f2 := s2.Field(i)
if f2.CanSet() {
s2.Field(i).Set(f1.Addr())
}
}
}
func KeepFields(t interface{}, fieldsToKeep arrayOfStrings) {
s := reflect.ValueOf(t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
if !fieldsToKeep.Contains(typeOfT.Field(i).Name) && f.CanSet() {
s.Field(i).Set(reflect.Zero(typeOfT.Field(i).Type))
}
}
}
func InitPointerStructure( pSrc interface{}, pDest interface{}, fieldsToKeep arrayOfStrings) {
CopyToPointerStructure(pSrc, pDest)
KeepFields(pDest, fieldsToKeep)
}
func main() {
var a TA
a.Field1 = "foo"
a.Field2 = "bar"
a.IsSomething = false
var b TB
toKeep := []string{"Field1"}
InitPointerStructure(&a,&b, toKeep)
resA, _ := json.Marshal(a)
fmt.Printf("A: %s\n", resA)
resB, _ := json.Marshal(b)
fmt.Printf("B: %s\n", resB)
// A: {"Field1":"foo","Field2":"bar","IsSomething":false}
// B: {"Field1":"foo"}
}
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type TA struct {
Field1 string
Field2 string
}
type TB struct {
Field1 string `json:",omitempty"`
Field2 string `json:",omitempty"`
}
type TC struct {
Field1 string `json:",omitempty"`
Field2 string `json:",omitempty"`
IsSomething bool `json:",omitempty"`
}
type TD struct {
Field1 *string `json:",omitempty"`
Field2 *string `json:",omitempty"`
IsSomething *bool `json:",omitempty"`
}
func omitFields(t interface{}) {
s := reflect.ValueOf(t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
if typeOfT.Field(i).Name != "Field1" && typeOfT.Field(i).Name != "IsSomething" {
if f.CanSet() {
s.Field(i).Set(reflect.Zero(typeOfT.Field(i).Type))
}
}
}
}
func main() {
var a TA
a.Field1 = "foo"
a.Field2 = "bar"
var b TB
b.Field1 = "foobar"
var c1 TC
c1.Field1 = "foobarfoo"
c1.IsSomething = true
var c2 TC
c2.Field1 = "barfoobar"
c2.IsSomething = false // not display as false value is consider an "empty value" http://golang.org/pkg/encoding/json/#Marshal
var d1 TD
s := "run you fools"
isNotSomething := false
d1.Field1 = &s
d1.IsSomething = &isNotSomething
var d2 TD
s1 := "domo"
s2 := "arigato"
isSomething := false
d2.Field1 = &s1
d2.Field2 = &s2
d2.IsSomething = &isSomething
resA, _ := json.Marshal(a)
resB, _ := json.Marshal(b)
resC1, _ := json.Marshal(c1)
resC2, _ := json.Marshal(c2)
resD1, _ := json.Marshal(d1)
resD2, _ := json.Marshal(d2)
fmt.Printf("A: %s\nB: %s\nC1: %s\nC2: %s\nD1: %s\nD2: %s\n", resA, resB, resC1, resC2, resD1, resD2)
omitFields(&d2)
resD2, _ = json.Marshal(d2)
fmt.Printf("Omited D2: %s\n", resD2)
// results:
//A: {"Field1":"foo","Field2":"bar"}
//B: {"Field1":"foobar"}
//C1: {"Field1":"foobarfoo","IsSomething":true}
//C2: {"Field1":"barfoobar"}
//D1: {"Field1":"run you fools","IsSomething":false}
//D2: {"Field1":"domo","Field2":"arigato","IsSomething":false}
//Omited D2: {"Field1":"domo","IsSomething":false}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment