encoding/{protojson,prototext}: add MustUnmarshal function
I'm noticing that text serialization (and to some degree JSON) is used to quickly initialize a lot of data in tests (and sometimes in not-test code at init) with a pattern like:
const initData = `...` // text data
m := new(foopb.MyMessage)
if err := prototext.Unmarshal([]byte(initData), m); err != nil {
panic(err)
}
return m
With the upcoming introduction of generics, perhaps we should add a helper for this:
func MustUnmarshal[M proto.Message](s string) M {
var m M
m = m.ProtoReflect().New().Interface()
if err := Unmarshal([]byte(s), m); err != nil {
panic(err)
}
return m
}
Thus, usage of this would be something like:
m := prototext.MustUnmarshal[*foopb.MyMessage](initData)
:grimacing: I‘m not sure about reinforcing a habit of unmarshalling const string into a proto message for initialization, rather than just building the proto‘s complex literal directly…
But then, if we don‘t do it the right way, someone might implement it in a subtly buggy way?
I‘m not sure about reinforcing a habit of unmarshalling const string into a proto message for initialization
True, I'm not fond of having multiple ways of doing the same thing. This issue was filed primarily based on observation of a common code pattern, which suggest that some people want to initialize data this way instead of using struct literals. I don't feel strongly whether to have this or not.
I think the code will only be generated per use, so it should probably just increase size by O(1) per proto type called (combined O(n) on number of prototypes used by function). And hopefully, only in tests as well? :grimacing: I think it might be reasonable so that we give a definite answer on how to do this sort of thing? Maybe also with a note in the godoc about how it‘s primarily intended for tests, and that “we highly recommend just building the proto message as a complex literal instead.“
Could we maybe even export certain symbols only when we‘re in go test? But that seems iffy as well, as it would likely not show up in godoc, and thus not even find use where it would be a better replacement.
Maybe a specific prototestutils package? but :nauseated_face: the name.