Without any major changes, struct tags cannot solve the majority of the problems, because they do not propagate. The v1 MarshalJSON/UnmarshalJSON interfaces are too simplistic. At the very least, an alternative pair of interfaces should exist, which take options/flags/tags/whatever in the parameters. However, I agree this doesn't need to be in an entirely new package. It's not even hard to favor one interface over another:
switch ifc := val.(type) {
case MarshalJSONV2: // new interface, always used if present
case MarshalJSON: // old interface, fallback
default: // type isn't self-marshaling
}
The jsontext package is what's really revolutionary and needed here. The poor performance of the existing API is due primarily to the lack of a proper streaming API as the foundation. Using this as the basis for the new interfaces makes sense, and I agree that once this exists, the need for an entirely separate v2 package largely vanishes.
Comments
Without any major changes, struct tags cannot solve the majority of the problems, because they do not propagate. The v1 MarshalJSON/UnmarshalJSON interfaces are too simplistic. At the very least, an alternative pair of interfaces should exist, which take options/flags/tags/whatever in the parameters. However, I agree this doesn't need to be in an entirely new package. It's not even hard to favor one interface over another:
The jsontext package is what's really revolutionary and needed here. The poor performance of the existing API is due primarily to the lack of a proper streaming API as the foundation. Using this as the basis for the new interfaces makes sense, and I agree that once this exists, the need for an entirely separate v2 package largely vanishes.