Skip to content

Inconsistency in adjacently tagged enums #975

Description

@baloo

When using with=/deserialize_with=, it appears serde expects adjacently tagged enums to be in the following form:

use serde::Deserialize;

mod bar {
    use serde::de::Deserializer;

    use super::Foo;

    pub fn deserialize<'de, D>(_de: D) -> Result<Foo, D::Error>
    where
        D: Deserializer<'de>,
    {
        todo!()
    }
}

struct Foo;

#[derive(Deserialize)]
#[serde(tag="type", content="foo")]
enum Bar {
    #[serde(deserialize_with = "bar::deserialize")]
    Baz(Foo),
}

And that when the meta is placed within the variant, you get an error:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=72a2138a26f9d31c419d808261245156

error[E0277]: the trait bound `Foo: serde::Deserialize<'de>` is not satisfied

Meanwhile, serde-with appears to expect the meta next to the field of the variant:

use serde::{Deserialize, Serialize};
use serde_with::serde_as;

#[serde_as]
#[derive(Serialize, Deserialize)]
#[serde(tag = "type", content = "content")]
enum Foo {
    #[serde_as(as = "Base64")]
    Bar(Vec<u8>),
}

error: serde_as attribute is not allowed on enum variants
  --> src/lib.rs:10:5
   |
10 |     #[serde_as(as = "Base64")]
   |     ^

Using:

enum Foo {
    #[serde(with = "serde_with::As::<Base64>")]
    Bar(Vec<u8>),
}

appears to work around the immediate issue.

I'm not sure whether that is a bug in serde itself, or in serde-with, but I thought you might have an opinion!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions