google / starlark-go

Starlark in Go: the Starlark configuration language, implemented in Go
BSD 3-Clause "New" or "Revised" License
2.3k stars 209 forks source link

Provide methods for converting starlark.Value to/from interface{} #354

Closed edigaryev closed 3 years ago

edigaryev commented 3 years ago

Similarly to how google.golang.org/protobuf/types/known/structpb does the conversion:

For user-defined Value's an interface can be provided, similar to Golang's JSON Marshaler and Unmarshaler interfaces:

type ToInterface interface {
    ToInterface() (interface{}, error)
}

type FromInterface interface {
    FromInterface(interface{}) error
}

The error allows handling the case when an attempt to call ToInterface() is made on an outer Value which contains user-defined Value inside without ToInterface implemented.

These methods would simplify passing arbitrary YAML/JSON-compatible data structures as ordinary dict's/list's/etc to Starlark functions from Golang (e.g. Cirrus CLI uses Starlark to implement build/task hooks, and this conversion is currently done manually).

adonovan commented 3 years ago

I am wary of defining a standard function for converting Starlark values to Go values, or the reverse, because there are so many different ways to do it. For example, which Go integer type should a Starlark int value be mapped to? The smallest one capable of representing the value? int? *big.Int? How do you represent in Go a Starlark dict whose keys are (string, int) pairs? There are many sensible answers to such questions, and that suggests that no particular one belongs in the standard package. (A secondary concern is that such conversions invite very inefficient deep copying.)

Fortunately, there is no need for these functions to live in this repository. You can define your own conversion functions that do exactly what you want. If many users want the same function, it can be shared in a utility package. If the passage of time reveals a particularly good implementation, then let's talk about making it standard.

(By the way, see https://github.com/google/starlark-go/commit/ac23acb182e187e6835e4c0cc42205fe37a05624 for a standard Starlark JSON package that encoding and decoding operations for all the data types of JSON.)

edigaryev commented 3 years ago

Thanks for the quick reply 😀

Just wanted to vent the idea before actually making a PR and I think you have a point. In order to provide a one-size-fits-all implementation a bunch of options would probably need to be introduced that would control the conversion behavior.

Will close this for now.