use serde::{Deserialize, Deserializer, Serialize, Serializer};
macro_rules! open_set {
(
$(#[$meta:meta])*
pub enum $name:ident {
$( $(#[$vmeta:meta])* $variant:ident => $wire:literal, )+
}
) => {
$(#[$meta])*
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum $name {
$( $(#[$vmeta])* $variant, )+
Other(String),
}
impl $name {
pub const KNOWN: &'static [&'static str] = &[$($wire),+];
pub fn from_wire(value: &str) -> Self {
match value {
$( $wire => Self::$variant, )+
other => Self::Other(other.to_owned()),
}
}
pub fn as_str(&self) -> &str {
match self {
$( Self::$variant => $wire, )+
Self::Other(other) => other,
}
}
pub fn is_known(&self) -> bool {
!matches!(self, Self::Other(_))
}
}
impl Serialize for $name {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for $name {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let value = String::deserialize(deserializer)?;
Ok(Self::from_wire(&value))
}
}
};
}
open_set! {
pub enum Verdict {
ColdStart => "cold_start",
Stable => "stable",
Warning => "warning",
Bust => "bust",
FullBust => "full_bust",
Unknown => "unknown",
}
}
open_set! {
pub enum StepSource {
File => "file",
Runner => "runner",
}
}
open_set! {
pub enum RequestSize {
Smaller => "smaller",
NotSmaller => "not_smaller",
}
}