diff --git a/rlp/decode.go b/rlp/decode.go index c4e5869cc..ee0b7dbcd 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -63,12 +63,16 @@ type Decoder interface { // must contain an element for each decoded field. Decode returns an // error if there are too few or too many elements. // -// The decoding of struct fields honours two struct tags, "tail" and -// "nil". For an explanation of "tail", see the example. -// The "nil" tag applies to pointer-typed fields and changes the -// decoding rules for the field such that input values of size zero -// decode as a nil pointer. This tag can be useful when decoding -// recursive types. +// The decoding of struct fields honours certain struct tags, "tail", +// "nil" and "-". +// +// The "-" tag ignores fields. +// +// For an explanation of "tail", see the example. +// +// The "nil" tag applies to pointer-typed fields and changes the decoding +// rules for the field such that input values of size zero decode as a nil +// pointer. This tag can be useful when decoding recursive types. // // type StructWithEmptyOK struct { // Foo *[20]byte `rlp:"nil"` diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 2d465b74d..d762e195d 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -339,6 +339,12 @@ var ( ) ) +type hasIgnoredField struct { + A uint + B uint `rlp:"-"` + C uint +} + var decodeTests = []decodeTest{ // booleans {input: "01", ptr: new(bool), value: true}, @@ -490,6 +496,13 @@ var decodeTests = []decodeTest{ value: tailRaw{A: 1, Tail: []RawValue{}}, }, + // struct tag "-" + { + input: "C20102", + ptr: new(hasIgnoredField), + value: hasIgnoredField{A: 1, C: 2}, + }, + // RawValue {input: "01", ptr: new(RawValue), value: RawValue(unhex("01"))}, {input: "82FFFF", ptr: new(RawValue), value: RawValue(unhex("82FFFF"))}, diff --git a/rlp/encode_test.go b/rlp/encode_test.go index 6f38294e4..827960f7c 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -218,6 +218,7 @@ var encTests = []encTest{ {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"}, {val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"}, {val: &tailRaw{A: 1, Tail: nil}, output: "C101"}, + {val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"}, // nil {val: (*uint)(nil), output: "80"}, diff --git a/rlp/typecache.go b/rlp/typecache.go index a2f217c66..3df799e1e 100644 --- a/rlp/typecache.go +++ b/rlp/typecache.go @@ -37,11 +37,12 @@ type typeinfo struct { type tags struct { // rlp:"nil" controls whether empty input results in a nil pointer. nilOK bool - // rlp:"tail" controls whether this field swallows additional list // elements. It can only be set for the last field, which must be // of slice type. tail bool + // rlp:"-" ignores fields. + ignored bool } type typekey struct { @@ -101,6 +102,9 @@ func structFields(typ reflect.Type) (fields []field, err error) { if err != nil { return nil, err } + if tags.ignored { + continue + } info, err := cachedTypeInfo1(f.Type, tags) if err != nil { return nil, err @@ -117,6 +121,8 @@ func parseStructTag(typ reflect.Type, fi int) (tags, error) { for _, t := range strings.Split(f.Tag.Get("rlp"), ",") { switch t = strings.TrimSpace(t); t { case "": + case "-": + ts.ignored = true case "nil": ts.nilOK = true case "tail":