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

How to serialize PlatformRoute, Tier, Division, etc? #33

Open
VRichardJP opened this issue Nov 1, 2021 · 2 comments
Open

How to serialize PlatformRoute, Tier, Division, etc? #33

VRichardJP opened this issue Nov 1, 2021 · 2 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@VRichardJP
Copy link

Some structures like Match derive serde::Serialize and serde::Deserialize for parsing purpose but a few enums don't. Is there a reason?

For example, I would like to create a serializable structure like this:

#[derive(Serialize, Deserialize)]
pub struct config {
    pub version: String,
    pub servers: Vec<PlatformRoute>,
    pub tiers: Vec<Tier>
}
@MingweiSamuel
Copy link
Owner

To answer, anything that shows up in JSON responses returned by the API derive serde (though I guess only the de is needed), and things like PlatformRoute don't since they don't show up in the JSON.

Tier and Division actually do implement serde manually (not derive) since they're serialized as strings rather than numbers in the JSON.


The easiest way to deal with this in current form would be with a newtype and serde impl, something like this: (untested)

pub struct PlatformRouteSerde(pub PlatformRoute);

impl<'de> serde::de::Deserialize<'de> for PlatformRouteSerde {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>
    {
        let num = u8::deserialize(deserializer)?;
        let route = num.parse().map_err(serde::de::Error::custom)?;
        PlatformRouteSerde(route)
    }
}

impl serde::ser::Serialize for PlatformRouteSerde {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_u8(self.0.into())
    }
}

@MingweiSamuel MingweiSamuel added enhancement New feature or request question Further information is requested labels Nov 1, 2021
@VRichardJP
Copy link
Author

Thanks, I just saw the serde_string macro. Regarding Tier and Division I feel the macro is redundant: #derive(serde::Serialize) does stringify the enum variant by default (while #derive(serde_repr::Serialize_repr) would use the repr value instead). For example:

use serde_repr::{Serialize_repr, Deserialize_repr};
use serde::{Serialize, Deserialize};

#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
enum SmallPrimeRepr {
    Two = 2,
    Three = 3,
    Five = 5,
    Seven = 7,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[repr(u8)]
enum SmallPrime {
    Two = 2,
    Three = 3,
    Five = 5,
    Seven = 7,
}

fn main() -> serde_json::Result<()> {
    let j_repr = serde_json::to_string(&SmallPrimeRepr::Seven)?;
    let j = serde_json::to_string(&SmallPrime::Seven)?;
    println!("{} {}", j_repr, j);

    let p_repr: SmallPrimeRepr = serde_json::from_str("2")?;
    let p: SmallPrime = serde_json::from_str("\"Two\"")?;
    println!("{:?} {:?}", p_repr, p);

    Ok(())
}

prints:

7 "Seven"
Two Two

So I think for Tier/Division a simple #derive(serde::Serialize) would do. For PlatformRoute I guess it is not that easy because then there is the issue with serde <-> strum serialization consistency =/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants