From 8a7e607474b2c36b681c77de8a9860af1553829a Mon Sep 17 00:00:00 2001 From: Ashlie Martinez Date: Fri, 31 Mar 2023 12:42:03 -0700 Subject: [PATCH] Fucntion to decode manifests with custom code --- src/cmd/jsondebug/decoder/decoder.go | 16 ++++++ src/cmd/jsondebug/decoder/manifst_decoder.go | 59 ++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/cmd/jsondebug/decoder/manifst_decoder.go diff --git a/src/cmd/jsondebug/decoder/decoder.go b/src/cmd/jsondebug/decoder/decoder.go index 3ebdedd6a..df4838cab 100644 --- a/src/cmd/jsondebug/decoder/decoder.go +++ b/src/cmd/jsondebug/decoder/decoder.go @@ -40,6 +40,22 @@ func expectDelimToken(dec *json.Decoder, expectedToken string) error { return nil } +func stringToken(dec *json.Decoder) (string, error) { + t, err := dec.Token() + if errors.Is(err, io.EOF) { + return "", errors.WithStack(errEOF) + } else if err != nil { + return "", errors.Wrap(err, "reading JSON token") + } + + l, ok := t.(string) + if !ok { + return "", errors.Errorf("unexpected token (%T) %v; wanted field name", t, t) + } + + return l, nil +} + func DecodeFooArray(r io.Reader) (common.FooArray, error) { var ( dec = json.NewDecoder(r) diff --git a/src/cmd/jsondebug/decoder/manifst_decoder.go b/src/cmd/jsondebug/decoder/manifst_decoder.go new file mode 100644 index 000000000..5dc7232da --- /dev/null +++ b/src/cmd/jsondebug/decoder/manifst_decoder.go @@ -0,0 +1,59 @@ +package decoder + +import ( + "encoding/json" + "io" + + "github.com/pkg/errors" + + "github.com/alcionai/corso/src/cmd/jsondebug/common" +) + +func DecodeManifestArray(r io.Reader) (common.Manifest, error) { + var ( + dec = json.NewDecoder(r) + res = common.Manifest{} + ) + + if err := expectDelimToken(dec, objectOpen); err != nil { + return res, err + } + + // Need to manually decode fields here since we can't reuse the stdlib + // decoder due to memory issues. + if err := parseManifestFields(dec, &res); err != nil { + return res, err + } + + // Consumes closing object curly brace after we're done. Don't need to check + // for EOF because json.Decode only guarantees decoding the next JSON item in + // the stream so this follows that. + return res, expectDelimToken(dec, objectClose) +} + +func parseManifestFields(dec *json.Decoder, res *common.Manifest) error { + var seen bool + + for dec.More() { + l, err := stringToken(dec) + if err != nil { + return err + } + + // Only have `entries` field right now. This is stricter than the current + // JSON decoder in the stdlib. + if l != "entries" { + return errors.Errorf("unexpected field name %s", l) + } else if seen { + return errors.New("repeated Entries field") + } + + seen = true + + if err := decodeArray(dec, &res.Entries); err != nil { + return err + } + } + + return nil +}