use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
#[serde(transparent)]
pub struct ObjectId(u64);
impl ObjectId {
pub const fn new(value: u64) -> Self {
Self(value)
}
pub const fn value(self) -> u64 {
self.0
}
}
impl fmt::Display for ObjectId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u64> for ObjectId {
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<ObjectId> for u64 {
fn from(id: ObjectId) -> Self {
id.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_and_value_round_trip() {
assert_eq!(ObjectId::new(0).value(), 0);
assert_eq!(ObjectId::new(u64::MAX).value(), u64::MAX);
assert_eq!(ObjectId::new(1_108_165_575).value(), 1_108_165_575);
}
#[test]
fn display_is_bare_integer() {
assert_eq!(ObjectId::new(42).to_string(), "42");
assert_eq!(ObjectId::new(0).to_string(), "0");
}
#[test]
fn from_conversions() {
let id: ObjectId = 7u64.into();
assert_eq!(id, ObjectId::new(7));
let raw: u64 = ObjectId::new(7).into();
assert_eq!(raw, 7);
}
#[test]
fn serde_is_transparent_bare_integer() {
let id = ObjectId::new(40_257_166);
let json = serde_json::to_string(&id).unwrap();
assert_eq!(json, "40257166");
let back: ObjectId = serde_json::from_str(&json).unwrap();
assert_eq!(back, id);
let some: Option<ObjectId> = Some(id);
assert_eq!(serde_json::to_string(&some).unwrap(), "40257166");
let none: Option<ObjectId> = None;
assert_eq!(serde_json::to_string(&none).unwrap(), "null");
}
#[test]
fn equality_enables_link_check() {
let target = Some(ObjectId::new(123));
let referencer = ObjectId::new(123);
assert_eq!(target, Some(referencer));
}
}