From fde10d6a43960f6e689cad04aee11e999d1a7238 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 10 Nov 2021 12:03:44 +0000 Subject: [PATCH] support for cborgen struct field tags --- gen.go | 12 +++- testgen/main.go | 1 + testing/cbor_map_gen.go | 137 ++++++++++++++++++++++++++++++++++++++++ testing/types.go | 17 +++-- 4 files changed, 159 insertions(+), 8 deletions(-) diff --git a/gen.go b/gen.go index e93e00c..cc197d0 100644 --- a/gen.go +++ b/gen.go @@ -75,6 +75,7 @@ var _ = sort.Sort type Field struct { Name string + MapKey string Pointer bool Type reflect.Type Pkg string @@ -194,8 +195,15 @@ func ParseTypeInfo(i interface{}) (*GenTypeInfo, error) { pointer = true } + mapk := f.Name + tagval := f.Tag.Get("cborgen") + if tagval != "" { + mapk = tagval + } + out.Fields = append(out.Fields, Field{ Name: f.Name, + MapKey: mapk, Pointer: pointer, Type: ft, Pkg: pkg, @@ -1129,7 +1137,7 @@ func emitCborMarshalStructMap(w io.Writer, gti *GenTypeInfo) error { fmt.Fprintf(w, "\n\t// t.%s (%s) (%s)", f.Name, f.Type, f.Type.Kind()) if err := emitCborMarshalStringField(w, Field{ - Name: `"` + f.Name + `"`, + Name: `"` + f.MapKey + `"`, }); err != nil { return err } @@ -1224,7 +1232,7 @@ func (t *{{ .Name}}) UnmarshalCBOR(r io.Reader) error { fmt.Fprintf(w, "// t.%s (%s) (%s)", f.Name, f.Type, f.Type.Kind()) err := doTemplate(w, f, ` - case "{{ .Name }}": + case "{{ .MapKey }}": `) if err != nil { return err diff --git a/testgen/main.go b/testgen/main.go index c94aee7..90f2224 100644 --- a/testgen/main.go +++ b/testgen/main.go @@ -22,6 +22,7 @@ func main() { types.NeedScratchForMap{}, types.SimpleStructV1{}, types.SimpleStructV2{}, + types.RenamedFields{}, ); err != nil { panic(err) } diff --git a/testing/cbor_map_gen.go b/testing/cbor_map_gen.go index b7d9000..7be3cf8 100644 --- a/testing/cbor_map_gen.go +++ b/testing/cbor_map_gen.go @@ -1592,3 +1592,140 @@ func (t *SimpleStructV2) UnmarshalCBOR(r io.Reader) error { return nil } +func (t *RenamedFields) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{162}); err != nil { + return err + } + + scratch := make([]byte, 9) + + // t.Foo (int64) (int64) + if len("foo") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"foo\" was too long") + } + + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("foo"))); err != nil { + return err + } + if _, err := io.WriteString(w, string("foo")); err != nil { + return err + } + + if t.Foo >= 0 { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Foo)); err != nil { + return err + } + } else { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Foo-1)); err != nil { + return err + } + } + + // t.Bar (string) (string) + if len("beep") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"beep\" was too long") + } + + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("beep"))); err != nil { + return err + } + if _, err := io.WriteString(w, string("beep")); err != nil { + return err + } + + if len(t.Bar) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Bar was too long") + } + + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Bar))); err != nil { + return err + } + if _, err := io.WriteString(w, string(t.Bar)); err != nil { + return err + } + return nil +} + +func (t *RenamedFields) UnmarshalCBOR(r io.Reader) error { + *t = RenamedFields{} + + br := cbg.GetPeeker(r) + scratch := make([]byte, 8) + + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("RenamedFields: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadStringBuf(br, scratch) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.Foo (int64) (int64) + case "foo": + { + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Foo = int64(extraI) + } + // t.Bar (string) (string) + case "beep": + + { + sval, err := cbg.ReadStringBuf(br, scratch) + if err != nil { + return err + } + + t.Bar = string(sval) + } + + default: + // Field doesn't exist on this type, so ignore it + cbg.ScanForLinks(r, func(cid.Cid) {}) + } + } + + return nil +} diff --git a/testing/types.go b/testing/types.go index 09216a9..7941ab5 100644 --- a/testing/types.go +++ b/testing/types.go @@ -45,12 +45,12 @@ type SimpleTypeTree struct { } type SimpleStructV1 struct { - OldStr string - OldBytes []byte - OldNum uint64 - OldPtr *cid.Cid - OldMap map[string]SimpleTypeOne - OldArray []SimpleTypeOne + OldStr string + OldBytes []byte + OldNum uint64 + OldPtr *cid.Cid + OldMap map[string]SimpleTypeOne + OldArray []SimpleTypeOne OldStruct SimpleTypeOne } @@ -99,3 +99,8 @@ type ThingWithSomeTime struct { type NeedScratchForMap struct { Thing bool } + +type RenamedFields struct { + Foo int64 `cborgen:"foo"` + Bar string `cborgen:"beep"` +}