use std::fmt;
use eventide_macros::value_object;
pub trait ValueObject {
type Error;
fn validate(&self) -> Result<(), Self::Error>;
}
#[value_object]
#[derive(Copy, PartialOrd, Ord, Hash)]
pub struct Version(usize);
impl Version {
pub const fn new() -> Self {
Self(0)
}
pub const fn from_value(value: usize) -> Self {
Self(value)
}
pub fn next(&self) -> Self {
Self(self.0 + 1)
}
pub const fn value(&self) -> usize {
self.0
}
pub fn is_new(&self) -> bool {
self.0 == 0
}
pub fn is_created(&self) -> bool {
self.0 > 0
}
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "v{}", self.0)
}
}
impl From<usize> for Version {
fn from(value: usize) -> Self {
Self::from_value(value)
}
}
impl From<Version> for usize {
fn from(version: Version) -> Self {
version.value()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version_new() {
let v = Version::new();
assert_eq!(v.value(), 0);
assert!(v.is_new());
assert!(!v.is_created());
}
#[test]
fn test_version_from_value() {
let v = Version::from_value(5);
assert_eq!(v.value(), 5);
assert!(!v.is_new());
assert!(v.is_created());
}
#[test]
fn test_version_next() {
let v1 = Version::from_value(10);
let v2 = v1.next();
assert_eq!(v1.value(), 10);
assert_eq!(v2.value(), 11);
}
#[test]
fn test_version_ordering() {
let v0 = Version::from_value(0);
let v1 = Version::from_value(1);
let v2 = Version::from_value(2);
assert!(v1 > v0);
assert!(v2 > v1);
assert!(v2 >= v1);
assert!(v0 < v2);
assert_eq!(v1, Version::from_value(1));
}
#[test]
fn test_version_equality() {
let v1 = Version::from_value(5);
let v2 = Version::from_value(5);
let v3 = Version::from_value(6);
assert_eq!(v1, v2);
assert_ne!(v1, v3);
}
#[test]
fn test_version_display() {
let v0 = Version::new();
let v5 = Version::from_value(5);
assert_eq!(format!("{}", v0), "v0");
assert_eq!(format!("{}", v5), "v5");
}
#[test]
fn test_version_default() {
let v: Version = Default::default();
assert_eq!(v, Version::new());
assert_eq!(v.value(), 0);
}
#[test]
fn test_version_from_usize() {
let v: Version = 42.into();
assert_eq!(v.value(), 42);
}
#[test]
fn test_version_into_usize() {
let v = Version::from_value(42);
let num: usize = v.into();
assert_eq!(num, 42);
}
#[test]
fn test_version_is_created() {
let v0 = Version::new();
assert!(!v0.is_created());
let v1 = v0.next();
assert!(v1.is_created());
let v5 = Version::from_value(5);
assert!(v5.is_created());
}
#[test]
fn test_version_chaining() {
let v = Version::new().next().next().next();
assert_eq!(v.value(), 3);
}
#[test]
fn test_version_serde() {
let v = Version::from_value(42);
let json = serde_json::to_string(&v).unwrap();
assert_eq!(json, "42");
let deserialized: Version = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, v);
}
#[test]
fn test_version_clone() {
let v1 = Version::from_value(10);
let v2 = v1;
assert_eq!(v1, v2);
assert_eq!(v1.value(), v2.value());
}
}