Skip to content

OwnedLazyValue does not work in enum cases #84

@bluealert

Description

@bluealert

Describe the bug
When I have to deserialize several different json objects, I want to use enum to unify the deserialization. And I also want to use OwnedLazyValue, but I found that the OwnedLazyValue does not work in enum cases.

To Reproduce

use serde::Deserialize;
use serde_json::Value;
use sonic_rs::OwnedLazyValue;

#[derive(Debug, Deserialize)]
struct A {
    #[serde(deserialize_with = "deserialize_owned_lazy_value")]
    field1: OwnedLazyValue,
    field2: String,
}

#[derive(Debug, Deserialize)]
struct B {
    field_a: String,
    field_b: String,
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum JsonObject {
    A(A),
    B(B),
}

fn deserialize_owned_lazy_value<'de, D>(
    deserializer: D,
) -> Result<OwnedLazyValue, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let value = Value::deserialize(deserializer)?;
    sonic_rs::from_str(&value.to_string()).map_err(serde::de::Error::custom)
}

fn process_json(json_str: &str) {
    let json_obj: Result<JsonObject, _> = serde_json::from_str(json_str);

    match json_obj {
        Ok(JsonObject::A(a)) => {
            println!("A: {:?}, {:?}", a.field1, a.field2);
        }
        Ok(JsonObject::B(b)) => {
            println!("B: {:?}, {:?}", b.field_a, b.field_b);
        }
        Err(e) => eprintln!("Failed to parse JSON: {}", e),
    }
}

fn main() {
    let json_str1 = r#"{ "field1": "value1", "field2": "value2" }"#;
    let json_str2 = r#"{ "field_a": "valueA", "field_b": "valueB" }"#;

    process_json(json_str1);
    process_json(json_str2);
}

I must use deserialize_owned_lazy_value to deserialize field1.

Expected behavior

I want the OwnedLazyValue works as in not enum cases. I don't need to write my own deserialization function.

sonic-rs version:
0.3

Environment:
Ubuntu 22.04, Rust 1.77

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions