matcher: Intended Private Member Field Behavior is Incorrect #39
Description
I like the concept of copygen, where in theory the generated could approach ~20x faster than a json.Marshal -> protojson.Unmarshal
sandwich (and infinitely faster than jinzhu/copier).
However, when using on structs that aren't flat with concrete builtins, things seem to go a little sideways.
Is there something I'm missing on how to handle non-concrete builtin types?
Setup
By default, Created will be ignored because its name/type combo don't match between the structs, which makes sense.
However, with tag .* json
(which is required in my case) or adding a type override, copygen performs unexpectedly:
YML
generated:
setup: ./gen.go
output: ./generated/generated.go
Go
package copygen
import (
"time"
"google.golang.org/protobuf/runtime/protoimpl"
"google.golang.org/protobuf/types/known/timestamppb"
)
type Copygen interface {
EntityToPB(E *Entity) *EntityPB
EntityToPBCreated(E *Entity, Created *timestamppb.Timestamp) *EntityPB
// tag .* json
EntityToPBTag(E *Entity) *EntityPB
// tag .* json
EntityToPBCreatedTag(E *Entity, Created *timestamppb.Timestamp) *EntityPB
}
type Entity struct {
Created *time.Time `json:"created,omitempty"`
Name string `json:"name,omitempty"`
}
type EntityPB struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Created *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created,proto3,oneof" json:"created,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
}
Generation (gofmt
ed for better readability)
// Code generated by github.com/switchupcb/copygen
// DO NOT EDIT.
package copygen
import (
"time"
"google.golang.org/protobuf/runtime/protoimpl"
"google.golang.org/protobuf/types/known/timestamppb"
)
type EntityPB struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Created *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created,proto3,oneof" json:"created,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
}
type Entity struct {
Created *time.Time `json:"created,omitempty"`
Name string `json:"name,omitempty"`
}
// EntityToPB copies a *Entity to a *EntityPB.
func EntityToPB(tE *EntityPB, fE *Entity) {
// *EntityPB fields
tE.Name = fE.Name
}
// EntityToPBCreated copies a *Entity, *timestamppb.Timestamp to a *EntityPB.
func EntityToPBCreated(tE *EntityPB, fE *Entity, fT *timestamppb.Timestamp) {
// *EntityPB fields
tE.state = fT.state
tE.sizeCache = fT.sizeCache
tE.unknownFields = fT.unknownFields
tE.Created = fT
tE.Name = fE.Name
}
// EntityToPBTag copies a *Entity to a *EntityPB.
func EntityToPBTag(tE *EntityPB, fE *Entity) {
// *EntityPB fields
tE.Created = tE.Name = fE.Name
}
// EntityToPBCreatedTag copies a *Entity, *timestamppb.Timestamp to a *EntityPB.
func EntityToPBCreatedTag(tE *EntityPB, fE *Entity, fT *timestamppb.Timestamp) {
// *EntityPB fields
tE.Created.Seconds = fT.Seconds
tE.Created.Nanos = fT.Nanos
tE.Created = tE.Name = fE.Name
}
Errors
tE.state = fT.state
Copying private member fields isn't going to end well. ;-)
tE.Created = tE.Name = fE.Name
// ...
tE.Created = tE.Name = fE.Name
It seems like custom fields confuses the internal type-matching logic.
Operating System: darwin/arm64 or linux/amd64
Copygen Version: latest == v0.4.0