use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Priority {
Numeric(u64),
Text(String),
}
impl Default for Priority {
fn default() -> Self {
Priority::Numeric(0)
}
}
impl From<u64> for Priority {
fn from(n: u64) -> Self {
Priority::Numeric(n)
}
}
impl From<&str> for Priority {
fn from(s: &str) -> Self {
Priority::Text(s.to_owned())
}
}
impl From<String> for Priority {
fn from(s: String) -> Self {
Priority::Text(s)
}
}
impl std::fmt::Display for Priority {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Priority::Numeric(n) => write!(f, "{}", n),
Priority::Text(s) => write!(f, "{}", s),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serialize_numeric() {
let p = Priority::Numeric(42);
assert_eq!(serde_json::to_value(&p).unwrap(), serde_json::json!(42));
}
#[test]
fn serialize_text() {
let p = Priority::Text("alpha".to_owned());
assert_eq!(
serde_json::to_value(&p).unwrap(),
serde_json::json!("alpha")
);
}
#[test]
fn deserialize_numeric() {
let p: Priority = serde_json::from_value(serde_json::json!(100)).unwrap();
assert_eq!(p, Priority::Numeric(100));
}
#[test]
fn deserialize_text() {
let p: Priority = serde_json::from_value(serde_json::json!("beta")).unwrap();
assert_eq!(p, Priority::Text("beta".to_owned()));
}
#[test]
fn default_is_numeric_zero() {
assert_eq!(Priority::default(), Priority::Numeric(0));
}
#[test]
fn from_u64() {
let p: Priority = 99u64.into();
assert_eq!(p, Priority::Numeric(99));
}
#[test]
fn from_str() {
let p: Priority = "gamma".into();
assert_eq!(p, Priority::Text("gamma".to_owned()));
}
#[test]
fn from_string() {
let p: Priority = String::from("delta").into();
assert_eq!(p, Priority::Text("delta".to_owned()));
}
#[test]
fn display_numeric() {
assert_eq!(Priority::Numeric(7).to_string(), "7");
}
#[test]
fn display_text() {
assert_eq!(Priority::Text("foo".to_owned()).to_string(), "foo");
}
#[test]
fn round_trip_in_json_object() {
let body = serde_json::json!({
"queue": "test",
"priority": Priority::Numeric(50),
"payload": "hello"
});
assert_eq!(body["priority"], 50);
let body = serde_json::json!({
"queue": "test",
"priority": Priority::Text("abc".to_owned()),
"payload": "hello"
});
assert_eq!(body["priority"], "abc");
}
}