Closed torkelrogstad closed 3 years ago
I don't think this would be a good change, since it would silently discard type information. Right now you can safely write this for any type T:
var x T // some type T
v, err := structpb.NewValue(x)
if err != nil {
return err
}
x2 := v.Interface().(T) // the type stored in the value is the type returned by `v.Interface`
Relaxing the types of values passed to structpb.NewValue
would silently change the type stored in the value. Better to make the loss of type information explicit at creation time:
v, err := structpb.NewValue(string(x)) // very clear that the structpb.Value holds a string
This is fine for a string/string variant, but quickly gets hard if you're doing this with a more complext structure with structpb.NewStruct
. I've been working around this for now by doing a JSON marshal/unmarshal roundtrip, which feels "wrong"
structpb.NewValue
has to draw the line somewhere for what Go types it supports. The set currently supported are clearly documented and are either:
[]interface{}
for JSON arraymap[string]interface{}
for JSON objectsince there is an obvious mapping for them and the implementation is pretty straight-forward.
Expanding the list of supported types to more than the above would cause the implementation of structpb
to functionally have much of the same complexity as encoding/json
(which is non-trivial). We're not going to maintain that (and if we did provide the feature, our implementation would probably just do a roundtrip json.Marshal
and json.Unmarshal
anyways).
As such, it is entirely appropriate to do a round-trip marshal and unmarshal in the application code as it clearly surfaces what is functionally happening.
Closing as I don't think we'll be expanding the set of allowed types.
json.Marshal
and structpb.Value.UnmarshalJSON
.structpb
just as complicated as encoding/json
and I don't think it provides much performance benefit.
structpb.Value
.
Is your feature request related to a problem? Please describe. It is currently not possible to use methods from the
structpb
package, such asNewStruct
orNewValue
.Consider this program:
This errors with
proto: invalid type: main.customString
.Describe the solution you'd like I believe it makes sense for the
structpb
methods to convert custom types to its underlying types. In this case, that'd mean that doingstructpb.NewValue(customString("hey))
andstructpb.NewValue("hey")
would be identical.Additional context Go playgroud for this: https://play.golang.org/p/rtT2xqXI71u