rlp: add support for "-" struct tag

This commit is contained in:
Felix Lange 2017-03-07 12:37:53 +01:00
parent 667cd518ce
commit eee96a5bb7
4 changed files with 31 additions and 7 deletions

View File

@ -63,12 +63,16 @@ type Decoder interface {
// must contain an element for each decoded field. Decode returns an // must contain an element for each decoded field. Decode returns an
// error if there are too few or too many elements. // error if there are too few or too many elements.
// //
// The decoding of struct fields honours two struct tags, "tail" and // The decoding of struct fields honours certain struct tags, "tail",
// "nil". For an explanation of "tail", see the example. // "nil" and "-".
// The "nil" tag applies to pointer-typed fields and changes the //
// decoding rules for the field such that input values of size zero // The "-" tag ignores fields.
// decode as a nil pointer. This tag can be useful when decoding //
// recursive types. // 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 { // type StructWithEmptyOK struct {
// Foo *[20]byte `rlp:"nil"` // Foo *[20]byte `rlp:"nil"`

View File

@ -339,6 +339,12 @@ var (
) )
) )
type hasIgnoredField struct {
A uint
B uint `rlp:"-"`
C uint
}
var decodeTests = []decodeTest{ var decodeTests = []decodeTest{
// booleans // booleans
{input: "01", ptr: new(bool), value: true}, {input: "01", ptr: new(bool), value: true},
@ -490,6 +496,13 @@ var decodeTests = []decodeTest{
value: tailRaw{A: 1, Tail: []RawValue{}}, value: tailRaw{A: 1, Tail: []RawValue{}},
}, },
// struct tag "-"
{
input: "C20102",
ptr: new(hasIgnoredField),
value: hasIgnoredField{A: 1, C: 2},
},
// RawValue // RawValue
{input: "01", ptr: new(RawValue), value: RawValue(unhex("01"))}, {input: "01", ptr: new(RawValue), value: RawValue(unhex("01"))},
{input: "82FFFF", ptr: new(RawValue), value: RawValue(unhex("82FFFF"))}, {input: "82FFFF", ptr: new(RawValue), value: RawValue(unhex("82FFFF"))},

View File

@ -218,6 +218,7 @@ var encTests = []encTest{
{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"}, {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"},
{val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"}, {val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"},
{val: &tailRaw{A: 1, Tail: nil}, output: "C101"}, {val: &tailRaw{A: 1, Tail: nil}, output: "C101"},
{val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"},
// nil // nil
{val: (*uint)(nil), output: "80"}, {val: (*uint)(nil), output: "80"},

View File

@ -37,11 +37,12 @@ type typeinfo struct {
type tags struct { type tags struct {
// rlp:"nil" controls whether empty input results in a nil pointer. // rlp:"nil" controls whether empty input results in a nil pointer.
nilOK bool nilOK bool
// rlp:"tail" controls whether this field swallows additional list // rlp:"tail" controls whether this field swallows additional list
// elements. It can only be set for the last field, which must be // elements. It can only be set for the last field, which must be
// of slice type. // of slice type.
tail bool tail bool
// rlp:"-" ignores fields.
ignored bool
} }
type typekey struct { type typekey struct {
@ -101,6 +102,9 @@ func structFields(typ reflect.Type) (fields []field, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if tags.ignored {
continue
}
info, err := cachedTypeInfo1(f.Type, tags) info, err := cachedTypeInfo1(f.Type, tags)
if err != nil { if err != nil {
return nil, err 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"), ",") { for _, t := range strings.Split(f.Tag.Get("rlp"), ",") {
switch t = strings.TrimSpace(t); t { switch t = strings.TrimSpace(t); t {
case "": case "":
case "-":
ts.ignored = true
case "nil": case "nil":
ts.nilOK = true ts.nilOK = true
case "tail": case "tail":