Serde Deserialising an either type without knowing what either of the types are

I want to implement an either type, and I've defined it like this:

#[derive(Debug, Serialize, Deserialize)]
pub enum Either<T, U> {
	Left(T),
	Right(U),
}

I trued letting serde do the work of deserialising it but that didn't really work... So I tried manually implementing Deserialize for my type. For this, I did the usual impl legwork with a deserialize function within which I had a visitor. This is where I ran into a problem.

T and U could be any type so I want my visitor to be able to handle values of any type, just that if the value the visitor gets isn't of type T or U, I don't want it. But I don't know what T and U are. So far, I've just got autogenned implementations for each type that serde can handle. I'm not sure how I can say that I want to handle the value that the visitor gets based on the types of T and U.

Here's an example of what I mean:

// Within the visitor's impl
fn visit_bool<E>(self, v: bool) -> std::result::Result<Self::Value, E> where E: serde::de::Error {
        if T == bool { Ok(Either::Left(v)) }            // Can't really do this...
        else if U == bool { Ok(Either::Right(v)) }      // 
        else // ... Handle Error ...
}

This is looking a lot like runtime reflection at this point so I'm guessing I'm approaching this the wrong way... How could I do this right?

Sounds like you want the untagged enum representation.

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Either<T, U> {
    Left(T),
    Right(U),
}

It works by first trying to serialize as the first variant, and if that gives an error, it tries the second variant.

2 Likes

huh. I really need to re-read the docs.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.