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

DefaultOnError falls back to default unexpectedly #756

Closed
Skgland opened this issue Jun 10, 2024 · 2 comments
Closed

DefaultOnError falls back to default unexpectedly #756

Skgland opened this issue Jun 10, 2024 · 2 comments

Comments

@Skgland
Copy link

Skgland commented Jun 10, 2024

Attempting to roundtrip a value fails for the Bug struct in the reduced example below while it works for Working, the only difference being the DefaultOnError on the field field in Bug.

I would have expected both tests to pass but only test_working does.

use serde_with::{serde_as, DefaultOnError};

#[derive(Debug, Default, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum Enum {
    #[default]
    A,
    B,
}

#[serde_as]
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, PartialEq, Eq)]
pub struct Bug {
    #[serde_as(as = "DefaultOnError")]
    #[serde(default)]
    pub field: Enum,
}


#[serde_as]
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, PartialEq, Eq)]
pub struct Working {
    #[serde(default)]
    pub field: Enum,
}

#[test]
fn test_bug() {
    let val = Bug{
        field: Enum::B,
    };
    let data = ron::to_string(&val).unwrap();
    let nval = ron::from_str(&data).unwrap();
    assert_eq!(val, nval)
}


#[test]
fn test_working() {
    let val = Working{
        field: Enum::B,
    };
    let data = ron::to_string(&val).unwrap();
    let nval = ron::from_str(&data).unwrap();
    assert_eq!(val, nval)
}
[package]
name = "serde_with_bug"
version = "0.1.0"
edition = "2021"

[dependencies]
ron = "0.8.1"
serde = { version = "1.0.203", features = ["derive"] }
serde_with = "3.8.1"
@jonasbb
Copy link
Owner

jonasbb commented Jun 10, 2024

ron doesn't support round when a Value type is involved (e.g., for buffering). ron-rs/ron#397 That is a general issue with serde serde-rs/serde#1183.
Unfortunately, internal buffering is necessary for DefaultOnError to work. You cannot recover from Deserializer errors, as the Deserializer might be in an indeterminate state. The way around that is to deserialize into a type that will not fail, and then attempt to deserialize that into the target type.

@Skgland
Copy link
Author

Skgland commented Jun 10, 2024

Ah, ok, looks like this is a known issue with serde/ron then.

@Skgland Skgland closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants