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

Decoding into interface bug #405

Open
GRbit opened this issue Oct 3, 2022 · 6 comments
Open

Decoding into interface bug #405

GRbit opened this issue Oct 3, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@GRbit
Copy link

GRbit commented Oct 3, 2022

When I tried to unmarshal bytes into a struct hidden under a specific interface, "go-json" failed to unmarshal it. At the same time, go standard lib or json-iterator feels just fine with this approach.
Since you claim that your library is 100% compatible with the standard library, it makes sense to fix this bug or to change your README and add this exact case.

Code to reproduce the bug:

package main

import (
	"fmt"
	"github.com/goccy/go-json"
)

type EsDocument interface {
	IndexName() string
}

type Property struct {
	Name string `json:"name"`
}

func (p Property) IndexName() string {
	return "properties"
}

func main() {
	b := []byte(`{"name":"Test Property to remove"}`)
	p := Property{}

	unmarshallInterface(b, &p)

	fmt.Println(p)
}

func unmarshallInterface(body []byte, doc EsDocument) {
	if err := json.Unmarshal(body, &doc); err != nil {
		panic(err)
	}
}

Output

$ go run main.go
panic: json: cannot unmarshal main.EsDocument into Go value of type main.EsDocument

goroutine 1 [running]:
main.unmarshallInterface(...)
	/home/grbit/ssd/go/src/tst/main.go:31
main.main()
	/home/grbit/ssd/go/src/tst/main.go:24 +0x16d
exit status 2

If you change doc type name from EsDocument to just interface{} it'll work just fine.

package main

import (
	"fmt"
	"github.com/goccy/go-json"
)

type Property struct {
	Name string `json:"name"`
}

func main() {
	b := []byte(`{"name":"Test Property to remove"}`)
	p := Property{}

	unmarshallInterface(b, &p)

	fmt.Println(p)
}

func unmarshallInterface(body []byte, doc interface{}) {
	if err := json.Unmarshal(body, &doc); err != nil {
		panic(err)
	}
}

Output

$ go run main.go
{Test Property to remove}
@GRbit GRbit changed the title Unmarshalling interface bug Unmarshalling to interface bug Oct 4, 2022
@GRbit GRbit changed the title Unmarshalling to interface bug Decoding into interface bug Oct 4, 2022
@cmetallo42
Copy link

Solved!

cmetallo42 added a commit to cmetallo42/go-json that referenced this issue Oct 6, 2022
GRbit pushed a commit to GRbit/go-json that referenced this issue Oct 14, 2022
GRbit pushed a commit to GRbit/go-json that referenced this issue Oct 14, 2022
cmetallo42 added a commit to cmetallo42/go-json that referenced this issue Nov 14, 2022
@goccy goccy added the bug Something isn't working label Nov 15, 2022
@mymmrac
Copy link

mymmrac commented Jan 6, 2024

Hello @goccy, in #406 you said that you would fix this issue, the fix seems to be pretty small by itself, is there any chance you will do that any time soon? Thanks!

@GRbit
Copy link
Author

GRbit commented Jan 8, 2024

@mymmrac are you sure that the bug persists with the latest version? For me it works now.
Maybe your case is a little bit different? If so, it would be great if you could provide a test case reproducing the problem.

@mymmrac
Copy link

mymmrac commented Jan 8, 2024

@GRbit yes, it reproduces, here is an example:

package main

import (
	// "encoding/json"
	"fmt"

	"github.com/goccy/go-json"
)

func main() {
	s := Something{}
	s.Thing = &ThingA{}
	err := json.Unmarshal([]byte(`{"thing": {"a": 1}}`), &s)
	if err != nil {
		panic(err)
	}
	fmt.Println(s.Thing)
}

type Something struct {
	Thing Thing `json:"thing"`
}

type Thing interface {
	F()
}

type ThingA struct {
	A int `json:"a"`
}

func (t *ThingA) F() {}

With github.com/goccy/go-json - current master df897ae

panic: json: cannot unmarshal main.Thing into Go struct field Something.Thing of type main.Thing

With encoding/json - no issues, parsed as expected (s.Thing.A == 1)

@mymmrac
Copy link

mymmrac commented Jan 8, 2024

With this changes it works (from PR that was closed, #406):

replace github.com/goccy/go-json => github.com/cmetallo42/go-json v0.0.0-20221114111108-7fed434e8044

@GRbit
Copy link
Author

GRbit commented Jan 8, 2024

@mymmrac Indeed, you are right.

For some reason I thought that at some point it was fixed in goccy repository. Thank you for bringing this up again.

GRbit pushed a commit to GRbit/go-json that referenced this issue Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants