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

Coverage not detected when deserializing with custom derserializers (serde-json) #427

Closed
mickem opened this issue Mar 15, 2025 · 1 comment
Labels
C-upstream-bug Category: This is a bug of compiler or dependencies (the fix may require action in the upstream)

Comments

@mickem
Copy link

mickem commented Mar 15, 2025

Not really sure if this is an issue with this tool or with serde.

But I have noticed that frequently when I look at my coverage deserializers are not covered.
And at least when I have a custom deserializer this seems reproducible:

The following code seemingly test deserialization but coverage will report it as uncovered:

use serde::{Deserialize, Serialize};

pub mod base64 {
    use base64::{engine::general_purpose::STANDARD, Engine as _};
    use serde::{Deserialize, Serialize};
    use serde::{Deserializer, Serializer};
    pub fn serialize<S: Serializer>(v: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
        let base64 = STANDARD.encode(v);
        String::serialize(&base64, s)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
        let base64 = String::deserialize(d)?;
        STANDARD
            .decode(base64.as_bytes())
            .map_err(|e| serde::de::Error::custom(format!("Base64 decode error: {}", e)))
    }
}
#[derive(Deserialize, Debug, PartialEq)]
struct TLocJson {
    tag: u8,
    #[serde(with = "base64")]
    data: Vec<u8>,
}

fn main() {
}

#[cfg(test)]
mod tests {
    use crate::TLocJson;

    #[test]
    fn should_deserialize() {
        let json = r#"{"tag":1,"data":"AQID"}"#;
        let tloc: TLocJson = serde_json::from_str(json).unwrap();
        assert_eq!(
            tloc,
            TLocJson {
                tag: 1,
                data: vec![1, 2, 3]
            }
        );
    }

}

Image

If I remove the custom deserializer coverage works as expected.

Image

I don't really understand why it behaves like this and if this is expected behaviour or if this is an issue with serde or serde-json or my serializer please feel free to close this issue.

Cargo file for reference:

[package]
name = "rust-issue"
version = "0.1.0"
edition = "2021"

[dependencies]
serde_json = "1.0.140"
serde = { version = "1.0.219", features = ["derive"] }
base64 = "0.22.1"
@taiki-e
Copy link
Owner

taiki-e commented Mar 18, 2025

serde's derive macros use #[automatically_derived], so they are usually automatically excluded from coverage (rust-lang/rust#120185).

The reason it could not be excluded when certain options were used is probably because it generated items (e.g., free-standing functions) that would not be covered by #[automatically_derived].

I would recommend suggesting to use coverage attribute it in the serde once it is stabilized (rust-lang/rust#134749).

Closing in favor of upstream issue on user-defined macros and coverage exclusions: rust-lang/rust#110486

@taiki-e taiki-e closed this as completed Mar 18, 2025
@taiki-e taiki-e added the C-upstream-bug Category: This is a bug of compiler or dependencies (the fix may require action in the upstream) label Mar 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-upstream-bug Category: This is a bug of compiler or dependencies (the fix may require action in the upstream)
Projects
None yet
Development

No branches or pull requests

2 participants