Use `#[derive(Serialize, Deserialize)]` for string enums missing `UNKNOWN(String)` variant

Use updated `serde_string!` -> `serde_strum_unknown!` for enums with
`UNKNOWN` variant.
pull/42/head
Mingwei Samuel 2022-06-20 10:04:02 -07:00
parent 104db04d9d
commit b24fdcb765
9 changed files with 50 additions and 43 deletions

View File

@ -1,6 +1,7 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use num_enum::{ IntoPrimitive, TryFromPrimitive }; use num_enum::{ IntoPrimitive, TryFromPrimitive };
use serde::{ Serialize, Deserialize };
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr }; use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
@ -15,6 +16,7 @@ use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
#[derive(Eq, PartialEq, Hash)] #[derive(Eq, PartialEq, Hash)]
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)] #[derive(EnumString, Display, AsRefStr, IntoStaticStr)]
#[derive(IntoPrimitive, TryFromPrimitive)] #[derive(IntoPrimitive, TryFromPrimitive)]
#[derive(Serialize, Deserialize)]
#[repr(u8)] #[repr(u8)]
pub enum Division { pub enum Division {
/// Division 1, the best/highest division in a [`Tier`](crate::consts::Tier), or the only division in /// Division 1, the best/highest division in a [`Tier`](crate::consts::Tier), or the only division in
@ -31,8 +33,6 @@ pub enum Division {
V = 5, V = 5,
} }
serde_string!(Division);
/// Returns a DoubleEndedIterator of I, II, III, IV. /// Returns a DoubleEndedIterator of I, II, III, IV.
/// Ordered from high rank (I) to low (IV). /// Ordered from high rank (I) to low (IV).
/// Excludes V, which is deprecated. /// Excludes V, which is deprecated.

View File

@ -70,5 +70,4 @@ pub enum GameMode {
URF, URF,
} }
string_enum_str!(GameMode); serde_strum_unknown!(GameMode);
serde_string!(GameMode);

View File

@ -6,12 +6,14 @@
// // // //
/////////////////////////////////////////////// ///////////////////////////////////////////////
use serde::{ Serialize, Deserialize };
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr }; use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
/// League of Legends game type: matched game, custom game, or tutorial game. /// League of Legends game type: matched game, custom game, or tutorial game.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[derive(Eq, PartialEq, Hash)] #[derive(Eq, PartialEq, Hash)]
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)] #[derive(EnumString, Display, AsRefStr, IntoStaticStr)]
#[derive(Serialize, Deserialize)]
#[repr(u8)] #[repr(u8)]
pub enum GameType { pub enum GameType {
/// Custom games /// Custom games
@ -21,5 +23,3 @@ pub enum GameType {
/// Tutorial games /// Tutorial games
TUTORIAL_GAME, TUTORIAL_GAME,
} }
serde_string!(GameType);

View File

@ -1,29 +1,12 @@
#![macro_use] #![macro_use]
macro_rules! serde_string { /// Macro for deriving `Serialize` and `Deserialize` for string enums with an
( $name:ident ) => { /// `UNKNOWN(String)` variant.
impl<'de> serde::de::Deserialize<'de> for $name { ///
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> /// Enum should have `#[derive(EnumString, IntoStaticStr)]` included.
where ///
D: serde::de::Deserializer<'de> /// Also implements `AsRef<str>`, `Display`, and `From<&str>`.
{ macro_rules! serde_strum_unknown {
let s = String::deserialize(deserializer)?;
s.parse().map_err(serde::de::Error::custom)
}
}
impl serde::ser::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.as_ref())
}
}
};
}
macro_rules! string_enum_str {
( $name:ident ) => { ( $name:ident ) => {
impl AsRef<str> for $name { impl AsRef<str> for $name {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
@ -33,12 +16,33 @@ macro_rules! string_enum_str {
} }
} }
} }
impl std::fmt::Display for $name { impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.as_ref().fmt(f) self.as_ref().fmt(f)
} }
} }
impl serde::ser::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.as_ref())
}
}
impl From<&str> for $name {
fn from(item: &str) -> Self {
item.parse().unwrap()
}
}
impl<'de> serde::de::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>
{
<&str>::deserialize(deserializer).map(Into::into)
}
}
} }
} }

View File

@ -318,8 +318,13 @@ newtype_enum! {
/// Ranked Teamfight Tactics (Hyper Roll) games on Convergence /// Ranked Teamfight Tactics (Hyper Roll) games on Convergence
CONVERGENCE_RANKED_TEAMFIGHT_TACTICS_HYPER_ROLL_ = 1130, CONVERGENCE_RANKED_TEAMFIGHT_TACTICS_HYPER_ROLL_ = 1130,
/// `1150`. /// `1150`.
/// Ranked Teamfight Tactics (Double Up Beta) games on Convergence /// Ranked Teamfight Tactics (Double Up Workshop) games on Convergence
CONVERGENCE_RANKED_TEAMFIGHT_TACTICS_DOUBLE_UP_BETA_ = 1150, /// Deprecated in patch 12.11 in favor of queueId 1160
#[deprecated(note="Deprecated in patch 12.11 in favor of queueId 1160")]
CONVERGENCE_RANKED_TEAMFIGHT_TACTICS_DOUBLE_UP_WORKSHOP__DEPRECATED_1150 = 1150,
/// `1160`.
/// Ranked Teamfight Tactics (Double Up Workshop) games on Convergence
CONVERGENCE_RANKED_TEAMFIGHT_TACTICS_DOUBLE_UP_WORKSHOP_ = 1160,
/// `1200`. /// `1200`.
/// Nexus Blitz games on Nexus Blitz /// Nexus Blitz games on Nexus Blitz
/// Deprecated in patch 9.2 in favor of queueId 1300 /// Deprecated in patch 9.2 in favor of queueId 1300

View File

@ -1,10 +1,10 @@
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr }; use strum_macros::{ EnumString, IntoStaticStr };
/// LoL or TFT ranked queue types. /// LoL or TFT ranked queue types.
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[derive(Eq, PartialEq, Hash)] #[derive(Eq, PartialEq, Hash)]
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)] #[derive(EnumString, IntoStaticStr)]
pub enum QueueType { pub enum QueueType {
/// Catch-all variant for new, unknown queue types. /// Catch-all variant for new, unknown queue types.
#[strum(default)] #[strum(default)]
@ -28,7 +28,7 @@ pub enum QueueType {
RANKED_TFT_PAIRS, RANKED_TFT_PAIRS,
} }
serde_string!(QueueType); serde_strum_unknown!(QueueType);
#[cfg(test)] #[cfg(test)]
mod test { mod test {

View File

@ -1,5 +1,6 @@
use strum::IntoEnumIterator;
use num_enum::{ IntoPrimitive, TryFromPrimitive }; use num_enum::{ IntoPrimitive, TryFromPrimitive };
use serde::{ Serialize, Deserialize };
use strum::IntoEnumIterator;
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr }; use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
/// LoL and TFT ranked tiers, such as gold, diamond, challenger, etc. /// LoL and TFT ranked tiers, such as gold, diamond, challenger, etc.
@ -13,6 +14,7 @@ use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
#[derive(Eq, PartialEq, Hash, PartialOrd, Ord)] #[derive(Eq, PartialEq, Hash, PartialOrd, Ord)]
#[derive(IntoPrimitive, TryFromPrimitive)] #[derive(IntoPrimitive, TryFromPrimitive)]
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)] #[derive(EnumString, Display, AsRefStr, IntoStaticStr)]
#[derive(Serialize, Deserialize)]
#[repr(u8)] #[repr(u8)]
pub enum Tier { pub enum Tier {
/// Challenger, the highest tier, an apex tier. Repr: `220_u8`. /// Challenger, the highest tier, an apex tier. Repr: `220_u8`.
@ -40,8 +42,6 @@ pub enum Tier {
UNRANKED = 0, UNRANKED = 0,
} }
serde_string!(Tier);
impl Tier { impl Tier {
/// If this tier is an apex tier: [`Self::MASTER`], [`Self::GRANDMASTER`], /// If this tier is an apex tier: [`Self::MASTER`], [`Self::GRANDMASTER`],
/// or [`Self::CHALLENGER`]. Returns false for [`Self::UNRANKED`]. /// or [`Self::CHALLENGER`]. Returns false for [`Self::UNRANKED`].

View File

@ -30,5 +30,4 @@ pub enum GameMode {
}} }}
} }
string_enum_str!(GameMode); serde_strum_unknown!(GameMode);
serde_string!(GameMode);

View File

@ -3,12 +3,14 @@
const gameTypes = require('./.gameTypes.json'); const gameTypes = require('./.gameTypes.json');
}}{{= dotUtils.preamble() }} }}{{= dotUtils.preamble() }}
use serde::{ Serialize, Deserialize };
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr }; use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
/// League of Legends game type: matched game, custom game, or tutorial game. /// League of Legends game type: matched game, custom game, or tutorial game.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[derive(Eq, PartialEq, Hash)] #[derive(Eq, PartialEq, Hash)]
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)] #[derive(EnumString, Display, AsRefStr, IntoStaticStr)]
#[derive(Serialize, Deserialize)]
#[repr(u8)] #[repr(u8)]
pub enum GameType { pub enum GameType {
{{ {{
@ -23,5 +25,3 @@ pub enum GameType {
} }
}} }}
} }
serde_string!(GameType);