Bläddra i källkod

Marshal fixed for pointers implementing Marshaler

This is a fix for the following situation:

  type T struct { /* ... */ }

  // MarshalCQL implements the gocql.Marshaler interface
  func (t *T) MarshalCQL(info TypeInfo) ([]byte, error) {
      // ...
  }

  func laterInTheCode() {

      t := &T{ /* ... */ }

      data, err := gocql.Marshal(info, t) // <-- won't work

      // ...
  }

Marshal resolves a pointer value before checking if it implements the
Marshaler interface. The code above won’t work because T doesn’t
implement the Marshaler interface, only *T does.

I added a test that shows the bug. The test fails without the fix and
passes with it.
Baptiste Fontaine 10 år sedan
förälder
incheckning
0c724b1117
3 ändrade filer med 23 tillägg och 0 borttagningar
  1. 1 0
      AUTHORS
  2. 2 0
      marshal.go
  3. 20 0
      marshal_test.go

+ 1 - 0
AUTHORS

@@ -48,3 +48,4 @@ Miles Delahunty <miles.delahunty@gmail.com>
 Zach Badgett <zach.badgett@gmail.com>
 Maciek Sakrejda <maciek@heroku.com>
 Jeff Mitchell <jeffrey.mitchell@gmail.com>
+Baptiste Fontaine <b@ptistefontaine.fr>

+ 2 - 0
marshal.go

@@ -53,6 +53,8 @@ func Marshal(info TypeInfo, value interface{}) ([]byte, error) {
 	if valueRef := reflect.ValueOf(value); valueRef.Kind() == reflect.Ptr {
 		if valueRef.IsNil() {
 			return nil, nil
+		} else if v, ok := value.(Marshaler); ok {
+			return v.MarshalCQL(info)
 		} else {
 			return Marshal(info, valueRef.Elem().Interface())
 		}

+ 20 - 0
marshal_test.go

@@ -774,3 +774,23 @@ func TestLookupCassType(t *testing.T) {
 		testType(t, lookupTest.TypeName, lookupTest.ExpectedType)
 	}
 }
+
+type MyPointerMarshaler struct{}
+
+func (m *MyPointerMarshaler) MarshalCQL(_ TypeInfo) ([]byte, error) {
+	return []byte{42}, nil
+}
+
+func TestMarshalPointer(t *testing.T) {
+	m := &MyPointerMarshaler{}
+	typ := NativeType{proto: 2, typ: TypeInt}
+
+	data, err := Marshal(typ, m)
+
+	if err != nil {
+		t.Errorf("Pointer marshaling failed. Error: %s", err)
+	}
+	if len(data) != 1 || data[0] != 42 {
+		t.Errorf("Pointer marshaling failed. Expected %+v, got %+v", []byte{42}, data)
+	}
+}