use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ReferralCode(u32);
impl ReferralCode {
pub const NONE: Self = Self(0);
pub const fn new(code: u32) -> Self {
Self(code)
}
pub const fn code(&self) -> u32 {
self.0
}
pub const fn is_none(&self) -> bool {
self.0 == 0
}
pub const fn is_some(&self) -> bool {
self.0 != 0
}
}
impl Default for ReferralCode {
fn default() -> Self {
Self::NONE
}
}
impl fmt::Display for ReferralCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_none() {
write!(f, "None")
} else {
write!(f, "{}", self.0)
}
}
}
impl From<ReferralCode> for u32 {
fn from(code: ReferralCode) -> Self {
code.0
}
}
impl From<u32> for ReferralCode {
fn from(code: u32) -> Self {
Self(code)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_none_constant() {
assert_eq!(ReferralCode::NONE.code(), 0);
assert!(ReferralCode::NONE.is_none());
assert!(!ReferralCode::NONE.is_some());
}
#[test]
fn test_new() {
let code = ReferralCode::new(42);
assert_eq!(code.code(), 42);
assert!(!code.is_none());
assert!(code.is_some());
let code = ReferralCode::new(0);
assert_eq!(code.code(), 0);
assert!(code.is_none());
assert!(!code.is_some());
let code = ReferralCode::new(u32::MAX);
assert_eq!(code.code(), u32::MAX);
assert!(code.is_some());
}
#[test]
fn test_default() {
let code = ReferralCode::default();
assert_eq!(code, ReferralCode::NONE);
assert_eq!(code.code(), 0);
}
#[test]
fn test_display() {
assert_eq!(format!("{}", ReferralCode::NONE), "None");
assert_eq!(format!("{}", ReferralCode::new(42)), "42");
assert_eq!(format!("{}", ReferralCode::new(1234)), "1234");
}
#[test]
fn test_conversions() {
let code = ReferralCode::new(42);
let value: u32 = code.into();
assert_eq!(value, 42);
let code: ReferralCode = 42u32.into();
assert_eq!(code.code(), 42);
}
#[test]
fn test_equality() {
assert_eq!(ReferralCode::new(42), ReferralCode::new(42));
assert_ne!(ReferralCode::new(42), ReferralCode::new(43));
assert_eq!(ReferralCode::NONE, ReferralCode::new(0));
}
#[test]
fn test_ordering() {
assert!(ReferralCode::new(1) < ReferralCode::new(2));
assert!(ReferralCode::new(100) > ReferralCode::new(50));
assert!(ReferralCode::NONE < ReferralCode::new(1));
}
#[test]
fn test_serialization() {
let code = ReferralCode::new(42);
let json = serde_json::to_string(&code).unwrap();
assert_eq!(json, "42");
let deserialized: ReferralCode = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.code(), 42);
let json = serde_json::to_string(&ReferralCode::NONE).unwrap();
assert_eq!(json, "0");
}
}