Open mpl opened 1 year ago
So it does not seem like "just" a representation problem. For example, if one runs the following program once with Go, then with Yaegi (or vice-versa), the second run fails, because the JSON representation cannot be decoded.
package main
import (
"encoding/json"
"errors"
"io/fs"
"io/ioutil"
"os"
"reflect"
)
func unmarshalJSON[T any](b []byte, x *[]T) error {
if *x != nil {
return errors.New("already initialized")
}
if len(b) == 0 {
return nil
}
return json.Unmarshal(b, x)
}
type Slice[T any] struct {
ж []T
}
func (v Slice[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
func (v *Slice[T]) UnmarshalJSON(b []byte) error { return unmarshalJSON(b, &v.ж) }
func StructOfSlice[T any](x []T) Slice[T] {
return Slice[T]{x}
}
type viewStruct struct {
Int int
Strings Slice[string]
StringsPtr *Slice[string] `json:",omitempty"`
}
func main() {
ss := StructOfSlice([]string{"bar"})
in := viewStruct{
Int: 1234,
Strings: ss,
StringsPtr: &ss,
}
thefile := "/Users/mpl/generics.json"
if _, err := os.Stat(thefile); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
panic(err)
}
println("WRITING FILE")
f, err := os.Create(thefile)
if err != nil {
panic(err)
}
defer f.Close()
encoder := json.NewEncoder(f)
encoder.SetIndent("", "")
if err1 := encoder.Encode(&in); err1 != nil {
panic(err)
}
return
}
println("READING FILE")
data, err := ioutil.ReadFile(thefile)
if err != nil {
panic(err)
}
var got viewStruct
if err2 := json.Unmarshal(data, &got); err2 != nil {
panic(err2)
}
println(reflect.DeepEqual(got, in))
}
The following program
sample.go
triggers an unexpected resultExpected result
Got
Yaegi Version
on top of https://github.com/traefik/yaegi/pull/1489
Additional Notes
Not sure if it's "only" a representation problem (some funkiness with the Stringer implementation?), or if it's actually a problem with the way yaegi handles the JSON encoding itself.