go-json-experiment / json

Experimental implementation of a proposed v2 encoding/json package
BSD 3-Clause "New" or "Revised" License
341 stars 11 forks source link

Question about Decoder.StackPointer #31

Open elv-gilles opened 2 months ago

elv-gilles commented 2 months ago

The following code:

package config_arshal_any_or_hook

import (
    "bytes"
    "fmt"
    "reflect"
    "testing"

    "github.com/go-json-experiment/json"
    "github.com/go-json-experiment/json/jsontext"
)

type Conf struct {
    Spaces
}

type Spaces struct {
    QSpaces []SubConf `json:"spaces"`
}

type SubConf struct {
    Id   string `json:"id"`
    Name string `json:"name"`
}

func (s *SubConf) initDef() {
    s.Name = "x"
}

func jsPath(s string) string {
    ret := s
    for len(ret) < 15 {
        ret += " "
    }
    return ret
}

func TestStackPointer(t *testing.T) {
    c := &Conf{}
    dec := jsontext.NewDecoder(bytes.NewReader([]byte(`{"spaces": [ {"id":"aa"}, {"id":"bb"} ] }`)))
    err := json.UnmarshalDecode(dec, c,
        json.WithUnmarshalers(
            json.UnmarshalFuncV2(func(dec *jsontext.Decoder, val any, opts json.Options) error {
                p := jsPath(dec.StackPointer())
                fmt.Println(p, "\t=>", reflect.TypeOf(val))
                switch x := val.(type) {
                case *SubConf:
                    x.initDef()
                }
                return json.SkipFunc
            }),
        ),
    )
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

produces the following output:

                    => *config_arshal_any_or_hook.Conf
/spaces             => *[]config_arshal_any_or_hook.SubConf
/spaces             => *config_arshal_any_or_hook.SubConf
/spaces/0/id        => *string
/spaces/0           => *config_arshal_any_or_hook.SubConf
/spaces/1/id        => *string

Is that correct ?

In particular, I would have expected to see: