Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: encoding/json: export tagOptions, parseTag #60770

Open
sparr opened this issue Jun 13, 2023 · 5 comments
Open

proposal: encoding/json: export tagOptions, parseTag #60770

sparr opened this issue Jun 13, 2023 · 5 comments
Labels
Milestone

Comments

@sparr
Copy link

sparr commented Jun 13, 2023

https://cs.opensource.google/go/go/+/master:src/encoding/json/tags.go

Multiple other packages reimplement similar functionality, including efforts to match the behavior of encoding/json:

Exporting this functionality would allow those and similar packages to have convenient access to identical behavior to the json package. It would even allow them to safely parse the json tag, if they so choose.

@sparr sparr added the Proposal label Jun 13, 2023
@gopherbot gopherbot added this to the Proposal milestone Jun 13, 2023
@apparentlymart
Copy link

The fact that non-JSON packages are trying to use the JSON package's tags seems to suggest that there's a missing abstraction here, for defining the relationship between properties in a serialization format and Go struct fields in a format-agnostic way.

While I expect it would be limited only to formats that have an infoset similar to JSON's, might it be better to expose a new struct tag scheme that is format-agnostic and then make encoding/json support it, rather than effectively "making it official" that the JSON package struct tags are the format-agnostic tags? 🤔

To make this alternative a bit more concrete for discussion, consider:

struct Example {
    Foo string `marshal:"foo"`
}

In the above, marshal is my hypothetical name for the format-agnostic struct tag type, with a parser for that format in its own dedicated package that encoding/json then depends on. I assume it would also support omitempty like the json struct tags do. Whether it should also support the other oddities like the string option is debatable; I've not researched how common that need is across other serialization formats. (e.g. in real-world YAML the exact type of a scalar is often just implied rather than explicit anyway.)

(I could also see just blessing "json" as the name for the general-purpose format as unfortunate but pragmatic, given that it paves an existing cowpath, but it is somewhat confusing for newcomers. I wonder what others think. I think accepting this proposal boils down to blessing "json" as the official format-agnostic name for "JSON-like" serialization formats -- whatever "JSON-like" might mean.)

@sparr
Copy link
Author

sparr commented Jun 14, 2023

https://gist.github.com/sparr/008ebfab065bd00c3dd903fa43b9ad55

I actually drafted something along those lines but decided to submit this first as lower hanging fruit.

@sparr
Copy link
Author

sparr commented Jun 14, 2023

To be clear, this proposal is about parsing what's inside a tag, the "name,flag,flag,flag" part. Nothing in the functions I'm proposing exposing is specific to the json: tag name. Those other packages could use it to parse the json tag, but they could also use it to parse the toml and yaml tags that they currently parse using their own parser implementations.

@ianlancetaylor
Copy link
Contributor

tagOptions and parseTag are pretty simple and don't have anything to do with JSON. If several different packages are implementing the same thing, that is an argument for providing this functionality somewhere in the standard library, but I don't see why encoding/json would be the right place for it.

We already have reflect.StructTag with Get and Lookup methods. We could perhaps extend that a bit, if somebody wants to think about what that might look like.

@sparr
Copy link
Author

sparr commented Jun 14, 2023

If we're going to expose these, I might also recommend benchmarking Contains current implementation (repeated strings.Cut) vs using a regular expression. The regex might look simpler and be faster.

I guess I should actually create that other proposal since that seems closer to what the feedback here is suggesting anyway.

@ianlancetaylor ianlancetaylor changed the title proposal: encoding/json: Export tagOptions, parseTag proposal: encoding/json: export tagOptions, parseTag Mar 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

4 participants