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

Doesn't work with untagged enums #20

Closed
imbolc opened this issue May 27, 2024 · 1 comment
Closed

Doesn't work with untagged enums #20

imbolc opened this issue May 27, 2024 · 1 comment

Comments

@imbolc
Copy link

imbolc commented May 27, 2024

#[derive(serde::Deserialize)]
pub struct Form {
    value: Vec<String>,
}

#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum EnumForm {
    Form(Form),
}

fn main() {
    // Works
    let _: Form = serde_html_form::from_str("value=&value=abc").unwrap();

    // Error("data did not match any variant of untagged enum EnumForm")
    let _: EnumForm = serde_html_form::from_str("value=&value=abc").unwrap();
}
@jplatte
Copy link
Owner

jplatte commented May 27, 2024

This is an instance of serde-rs/serde#1183, just like #18. There's nothing this library can do about it.

What you can do is write a Deserialize impl like this instead of relying on #[serde(untagged)]:

use serde::de::{Deserialize, Deserializer, Error as _};

impl<'de> Deserialize<'de> for EnumForm {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        struct FormStructRepr {
            #[serde(default)]
            mutually_exclusive_field_a: Vec<String>,
            mutually_exclusive_field_b: Option<u16>,
        }

        let s = FormStructRepr::deserialize(deserializer)?;
        match (s.mutually_exclusive_field_a.is_empty(), s.mutually_exclusive_field_b) {
            (false, None) => Ok(Self::FormA {
                value: s.mutually_exclusive_field_a,
            }),
            (true, Some(b_value)) => Ok(Self::FormB { value: b_value }),
            (false, Some(_)) => Err(D::Error::custom(
                "only one of mutually_exclusive_field_a, mutually_exclusive_field_b may be set",
            )),
            (true, None) => Err(D::Error::custom(
                "one of mutually_exclusive_field_a, mutually_exclusive_field_b must be set",
            )),
        }
    }
}

@jplatte jplatte closed this as not planned Won't fix, can't repro, duplicate, stale May 27, 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