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

Json<T> pattern Rust ecosystem #1033

Closed
ittorchbearer opened this issue Apr 23, 2022 · 2 comments
Closed

Json<T> pattern Rust ecosystem #1033

ittorchbearer opened this issue Apr 23, 2022 · 2 comments

Comments

@ittorchbearer
Copy link

ittorchbearer commented Apr 23, 2022

I'm starting to notice a pattern of many major libraries creating a Json<T> struct, and then they are all incompatible. Everything else works together nicely, but not this one item-- and working around it seems like not 'Rusty' unnecessary code bloat.

Examples:

rocket::serde::json::Json<T>
sqlx::types::Json<T>
actix

Usage example: data comes in from rocket web server and then gets saved with sqlx. Your only solution seems to be to use some custom adaptor approach. It gets really ugly as you move to libraries built on these base libraries.

You also end up with some other libs following other patterns that lose typing of the underlying structure. I believe a simple Json structure inside of the main lib would be good for the Rust community by allowing other libs to implement around that standard and thus leading to interoperability with this as the common interface.

What are your thoughts? Am I so lucky that there is a solution I'm missing?

@edgarogh
Copy link

The Rust standard library is supposed to be small in order not to be tempted to introduce non-backward-compatible changes. You will probably never see a struct named Json in an std lib that doesn't provide a way to generate random numbers.

As to why things are like that, it's simply because these kinds of structs are actually needed to provide the nice API of these 3 crates.

Take rocket. Json<T> needs to implement FromRequest and Responder. You can't just implement FromRequest for any deserializable trait because JSON is not the only deserialization method that exists, and because a lot of other FromRequest types do implement Deserialize but that's not how they should be build in a FromRequest context. By introducing a wrapper type, all these ambiguities are solved.

And honestly, I don't understand why you call this a "code bloat". These 3 structures all have one field and will probably be implemented transparently like T in RAM. Converting from one to the other has literally no cost.

@dtolnay dtolnay transferred this issue from serde-rs/serde Jul 9, 2023
@dtolnay
Copy link
Member

dtolnay commented Jul 9, 2023

If I understand correctly, the suggestion is to simply put the following into serde_json?

pub struct Json<T>(pub T);

I think I would prefer not to add this; the way JSON is currently handled by those crates seems all right to me.

@dtolnay dtolnay closed this as completed Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants