-
Notifications
You must be signed in to change notification settings - Fork 116
go fields: explicity support non-pointer marshalers #185
Conversation
Pull Request Test Coverage Report for Build 1142
💛 - Coveralls |
@@ -19,6 +19,18 @@ type Valuer struct { | |||
value reflect.Value | |||
} | |||
|
|||
var marshalerType = reflect.TypeOf((*marshaler)(nil)).Elem() | |||
|
|||
func nonPointerMarshal(d *Descriptor, val reflect.Value) (reflect.Value, bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: add a comment here explaining exactly what this is doing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
Naming the return types might help too (especially the bool)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with nits
internal/fields/sql.go
Outdated
|
||
func nonPointerMarshal(d *Descriptor, val reflect.Value) (reflect.Value, bool) { | ||
if !d.Ptr && reflect.PtrTo(d.Type).Implements(marshalerType) { | ||
fmt.Printf("typ: %+v, intf %v, intftyp: %T\n", d, val.Interface(), val.Interface()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove print?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoooops
@@ -229,8 +229,7 @@ func TestField_ValidateSQLType(t *testing.T) { | |||
{In: ifaceBinaryMarshal{}, Error: true}, | |||
{In: ifaceBinaryMarshal{}, Tags: []string{"binary"}, Error: false}, | |||
{In: &ifaceBinaryMarshal{}, Tags: []string{"binary"}, Error: false}, | |||
// Non-pointer proto does not work because the Marshal() method has a pointer receiver. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love it
0ff8421
to
420cf3e
Compare
As noted in my second commit with the benchmark, we see an increase of 1 allocation on the write path here (5 vs the typical 4). We're explicitly ok with this cost, given that:
|
What we see here is an additional allocation for the non-ptr proto to the heap. We expect this, since we have to create a new pointer in order to satisfy the marshaler interface. We deem this cost worth the additional safety of not having to deal with pointers. Since people have to opt-in to use this feature there isn't a noticeable difference to existing code-paths.
420cf3e
to
25dfb08
Compare
Because we sometimes might want to use non-pointers for protobuf, check our non-pointer types.
Test plan: