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

Support Serde for the built-in types #407

Open
ash0080 opened this issue Sep 12, 2023 · 6 comments
Open

Support Serde for the built-in types #407

ash0080 opened this issue Sep 12, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@ash0080
Copy link

ash0080 commented Sep 12, 2023

For example, Location. While it is possible to customize the serialization and deserialization process, it can become messy when it needs to be written in every place. It would be great if it could be a built-in feature.

@shepmaster shepmaster changed the title Wish the built-in types supported serde Supported Serde for the built-in types Sep 12, 2023
@shepmaster shepmaster added the enhancement New feature or request label Sep 12, 2023
@shepmaster
Copy link
Owner

Can you expand on what this will allow you to do that you cannot do today?

If this library serializes one specific Location as H4sIAPu7/2QAA6vmUlBQSsvMSVWyUlDSL8lI1U+tSEwu0S9ILMnQL8nXz8lM0isqVtIBKcvJzAMpszAxBHOT83NKc/OAAiamXLVcAF6603ZJAAAA, would that be sufficient for your case?

For example

You'll need to be specific about exactly which types would be useful.

@shepmaster shepmaster changed the title Supported Serde for the built-in types Support Serde for the built-in types Sep 12, 2023
@ash0080
Copy link
Author

ash0080 commented Sep 12, 2023

Can you expand on what this will allow you to do that you cannot do today?

If this library serializes one specific Location as H4sIAPu7/2QAA6vmUlBQSsvMSVWyUlDSL8lI1U+tSEwu0S9ILMnQL8nXz8lM0isqVtIBKcvJzAMpszAxBHOT83NKc/OAAiamXLVcAF6603ZJAAAA, would that be sufficient for your case?

For example

You'll need to be specific about exactly which types would be useful.

Are you referring to the UTF-8 encoding issue when converting from OsStr to str? If so, I believe there are already several secure character conversion crates available, or you can implement a custom closure-based conversion interface.

Actually, here's the situation: I'm working on writing a Tauri app, so naturally, I would like to display as complete error information as possible when I activate the console. Instead of logging in both the Rust and JavaScript sides, I would prefer if all the exposable built-in types could be converted into JSON, if possible. I have looked at the source code, and it seems that many of them only require adding a #derive. However, it is currently a bit cumbersome to manually implement this outside the crate, and it makes the code appear much more chaotic.

@shepmaster
Copy link
Owner

Are you referring to the UTF-8 encoding issue

No, I am not. My point is that you asked for Location to implement Serialize and Deserialize. I could straightforwardly implement those traits such that the serialized form of Location is that long ugly string. However, my guess is that would not be acceptable to you, even though it met your stated request. That's why I'm trying to extract information and details.

could be converted into JSON, if possible

writing a Tauri app [...] Rust and JavaScript sides

Right, here's more context. You don't just want something that can be serialized and deserialized, but you want something that can be serialized to JSON with a fixed and known serialization because you want to deserialize it outside of Rust.

Although it'd be supremely annoying, I could make it so that every time you compile the library the serialized field names changed, which I'd guess would not be acceptable to you, but would still allow roundtrip serialization/deserialization in a single process.

only require adding a #derive

Serialization is easy to add thanks to derive macros, but that doesn't mean that long-term support for serialized data is any easier. Serialization is another form of external interface that has to be carefully managed. For example, is it acceptable for the serialized form to change in a semver-compatible version? Do people expect that you can serialize a type with SNAFU 0.0.1 and then deserialize it later with SNAFU 0.1.0? That JSON could easily be written into a file and then loaded in a year.

many of them

Again, please list exactly which types you are talking about.

@shepmaster
Copy link
Owner

From a more positive standpoint, Location specifically is interesting for this because I've already made all the fields public, so the names and types are already fixed (with respect to semver, at least). For this one specific type, optionally adding derive(Deserialize, Serialize) would not be a big problem, and the docs would need to say that the serialized form follows the same semver constraints as the Rust type.

Even today, you could achieve this today by creating your own Location that implements Serialize, Deserialize, and GenerateImplicitData, potentially just wrapping snafu::Location and delegating where appropriate.

@ash0080
Copy link
Author

ash0080 commented Sep 12, 2023

#[snafu(display("{message}"))]
    Json {
        message: String,
        #[serde(serialize_with = "serialize_json_error")]
        source: serde_json::Error,
        #[serde(serialize_with = "serialize_location")]
        location: Location,
    },
    ...
    
    fn serialize_location<S>(x: &Location, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let mut state = s.serialize_struct("Location", 3)?;
    state.serialize_field("file", &x.file)?;
    state.serialize_field("line", &x.line)?;
    state.serialize_field("column", &x.column)?;
    state.end()
}

Yes, actually, this is a minor issue. I have carefully reviewed the documentation and it seems that the only type that may need to be exposed is Location. As for Backtrace, it would be even better if it could be serialized as an array. This way, it could potentially be combined with frontend code to achieve more pretty logs, such as if someone want to create a specific debug tool. However, in most cases, using strings should be sufficient.

@shepmaster
Copy link
Owner

As for Backtrace

This library doesn't really control Backtrace. Specifically, we have shim and inert implementations that we control but also allow directly re-exporting the backtrace or std crate's Backtrace type.

In a few versions, when the version support lines up, SNAFU will probably drop the shim and inert versions and just default to the standard library version and maybe allow swapping to the backtrace crate.

serialized as an array

For example, that's not yet stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants