From 81911ae4710d4cb7d0027dfa65f7a632c3ad7d23 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 2 Sep 2018 09:04:41 -0400 Subject: [PATCH] Enable fields to be marked for omission from a struct --- syntax/decode.go | 12 ++++++++++++ syntax/encode.go | 11 +++++++++++ syntax/success_test.go | 12 ++++++++++++ syntax/tags.go | 6 ++++++ 4 files changed, 41 insertions(+) diff --git a/syntax/decode.go b/syntax/decode.go index 1735840..ffcd010 100644 --- a/syntax/decode.go +++ b/syntax/decode.go @@ -102,6 +102,13 @@ func newTypeDecoder(t reflect.Type) decoderFunc { ///// Specific decoders below +func omitDecoder(d *decodeState, v reflect.Value, opts decOpts) int { + // This space intentionally left blank + return 0 +} + +////////// + func unmarshalerDecoder(d *decodeState, v reflect.Value, opts decOpts) int { um, ok := v.Interface().(Unmarshaler) if !ok { @@ -313,6 +320,11 @@ func newStructDecoder(t reflect.Type) decoderFunc { tag := f.Tag.Get("tls") tagOpts := parseTag(tag) + if tagOpts[omitOption] > 0 { + sd.fieldDecs[i] = omitDecoder + continue + } + sd.fieldOpts[i] = decOpts{ head: tagOpts["head"], max: tagOpts["max"], diff --git a/syntax/encode.go b/syntax/encode.go index 54fea59..ae649b8 100644 --- a/syntax/encode.go +++ b/syntax/encode.go @@ -96,6 +96,12 @@ func newTypeEncoder(t reflect.Type) encoderFunc { ///// Specific encoders below +func omitEncoder(e *encodeState, v reflect.Value, opts encOpts) { + // This space intentionally left blank +} + +////////// + func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.Kind() == reflect.Ptr && v.IsNil() { panic(fmt.Errorf("Cannot encode nil pointer")) @@ -243,6 +249,11 @@ func newStructEncoder(t reflect.Type) encoderFunc { tag := f.Tag.Get("tls") tagOpts := parseTag(tag) + if tagOpts[omitOption] > 0 { + se.fieldEncs[i] = omitEncoder + continue + } + se.fieldOpts[i] = encOpts{ head: tagOpts["head"], max: tagOpts["max"], diff --git a/syntax/success_test.go b/syntax/success_test.go index bb28f20..a915e2f 100644 --- a/syntax/success_test.go +++ b/syntax/success_test.go @@ -174,6 +174,18 @@ func TestSuccessCases(t *testing.T) { value: struct{ V *uint16 }{V: &dummyUint16}, encoding: unhex("B0A0"), }, + "struct-omit": { + value: struct { + A uint16 + B uint16 `tls:"omit"` + C uint16 + }{ + A: 0xA0A0, + B: 0x0000, // Can be anything on marshal, but will be zero on unmarshal + C: 0xC0C0, + }, + encoding: unhex("A0A0C0C0"), + }, // Marshaler "marshaler": { diff --git a/syntax/tags.go b/syntax/tags.go index e06f8ec..d944100 100644 --- a/syntax/tags.go +++ b/syntax/tags.go @@ -10,6 +10,7 @@ import ( type tagOptions map[string]uint var ( + omitOption = "omit" varintOption = "varint" headOptionNone = "none" @@ -24,6 +25,11 @@ var ( func parseTag(tag string) tagOptions { opts := tagOptions{} for _, token := range strings.Split(tag, ",") { + if token == omitOption { + opts[omitOption] = 1 + break + } + if token == varintOption { opts[varintOption] = 1 continue