From cc063bc9e51ede232b4880526b29a8e10433e9b4 Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 16 Jul 2019 05:14:21 +0900 Subject: [PATCH] automatically omit nil ptr of value types with custom encoding (fixes #99) --- encode.go | 21 ++++++++++++++++++++- encoding_test.go | 6 ++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/encode.go b/encode.go index 46abb31..792bde5 100644 --- a/encode.go +++ b/encode.go @@ -105,15 +105,34 @@ func Marshal(v interface{}) (*dynamodb.AttributeValue, error) { } func marshal(v interface{}, special string) (*dynamodb.AttributeValue, error) { + rv := reflect.ValueOf(v) switch x := v.(type) { case *dynamodb.AttributeValue: return x, nil case Marshaler: + if rv.Kind() == reflect.Ptr && rv.IsNil() { + if _, ok := rv.Type().Elem().MethodByName("MarshalDynamo"); ok { + // MarshalDynamo is defined on value type, but this is a nil ptr + return nil, nil + } + } return x.MarshalDynamo() case dynamodbattribute.Marshaler: + if rv.Kind() == reflect.Ptr && rv.IsNil() { + if _, ok := rv.Type().Elem().MethodByName("MarshalDynamoDBAttributeValue"); ok { + // MarshalDynamoDBAttributeValue is defined on value type, but this is a nil ptr + return nil, nil + } + } av := &dynamodb.AttributeValue{} return av, x.MarshalDynamoDBAttributeValue(av) case encoding.TextMarshaler: + if rv.Kind() == reflect.Ptr && rv.IsNil() { + if _, ok := rv.Type().Elem().MethodByName("MarshalText"); ok { + // MarshalText is defined on value type, but this is a nil ptr + return nil, nil + } + } text, err := x.MarshalText() if err != nil { return nil, err @@ -125,7 +144,7 @@ func marshal(v interface{}, special string) (*dynamodb.AttributeValue, error) { case nil: return nil, nil } - return marshalReflect(reflect.ValueOf(v), special) + return marshalReflect(rv, special) } var nilTm encoding.TextMarshaler diff --git a/encoding_test.go b/encoding_test.go index 4a0f352..4665bbf 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -3,9 +3,11 @@ package dynamo import ( "encoding" "strconv" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" ) const ( @@ -211,6 +213,10 @@ var itemEncodingTests = []struct { EmptyM map[string]bool EmptyPtr *int EmptyIface interface{} + NilTime *time.Time + NilCustom *customMarshaler + NilText *textMarshaler + NilAWS *dynamodbattribute.UnixTime }{ OK: "OK", EmptyL: []int{},