use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::convert::Infallible;
use std::str::FromStr;
use std::sync::Arc;
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct StatId(Arc<str>);
impl Serialize for StatId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.as_ref().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for StatId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(StatId::from(s))
}
}
impl StatId {
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Self {
Self(Arc::from(s))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl From<&str> for StatId {
fn from(s: &str) -> Self {
Self::from_str(s)
}
}
impl From<String> for StatId {
fn from(s: String) -> Self {
Self(Arc::from(s))
}
}
impl FromStr for StatId {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(Arc::from(s)))
}
}
impl std::fmt::Display for StatId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stat_id_creation() {
let id1 = StatId::from_str("HP");
let id2 = StatId::from_str("HP");
assert_eq!(id1, id2);
assert_eq!(id1.as_str(), "HP");
}
#[test]
fn test_stat_id_from_string() {
let id: StatId = "ATK".into();
assert_eq!(id.as_str(), "ATK");
}
#[test]
fn test_stat_id_ordering() {
let atk = StatId::from_str("ATK");
let hp = StatId::from_str("HP");
assert!(atk < hp); }
}