Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: custom MarshalJSON() on anonymous field blocks encoding of sibling struct fields #39915

Closed
BourgeoisBear opened this issue Jun 29, 2020 · 5 comments

Comments

@BourgeoisBear
Copy link

@BourgeoisBear BourgeoisBear commented Jun 29, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"

What did you do?

When I JSON encode a struct that embeds another struct (ICustom) as an anonymous field, and that struct (ICustom) implements MarshalJSON(), only ICustom is encoded, and other fields are omitted.

When I do the same thing, but where the embedded struct doesn't implement MarshalJSON(), all fields are included.

See: https://play.golang.org/p/VKH--_G432v

What did you expect to see?

The same output for both, given the code in the example.

What did you see instead?

Sibling fields omitted.

@mvdan
Copy link
Member

@mvdan mvdan commented Jun 29, 2020

This seems like a dupe of #39175.

@BourgeoisBear
Copy link
Author

@BourgeoisBear BourgeoisBear commented Jun 29, 2020

@mvdan in what way? #39715 is an unmarshaling issue. This is a marshaling one.

@mvdan
Copy link
Member

@mvdan mvdan commented Jun 29, 2020

It seems like the same root issue. Your method is being promoted to the main type, so it's being used to marshal the entire parent type, not just the embedded one. This is how methods in Go work.

@BourgeoisBear
Copy link
Author

@BourgeoisBear BourgeoisBear commented Jun 29, 2020

That explains it. Thanks.

@BourgeoisBear
Copy link
Author

@BourgeoisBear BourgeoisBear commented Jun 30, 2020

For the next person with this problem: you can embed a 2nd struct implementing a custom MarshalJSON(), and sibling fields will encode again. I made a dummy struct just for this purpose:

type JSON_Hack int

func (V JSON_Hack) MarshalJSON() ([]byte, error) {
	return []byte("null"), nil
}

type Example struct {
   Embed1WithCustomMarshaller
   JSON_Hack `json:"-"`
   Sibling1   int
   Sibling2   string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.