made_core/value_objects/audit/
global_position.rs1use serde::{Deserialize, Serialize};
2
3use crate::error::DomainError;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
14#[serde(transparent)]
15pub struct GlobalPosition(u64);
16
17impl GlobalPosition {
18 pub const FIRST: Self = Self(1);
20
21 pub fn new(value: u64) -> Result<Self, DomainError> {
22 if value == 0 {
23 return Err(DomainError::MustBeNonZero {
24 field: "global_position",
25 });
26 }
27 Ok(Self(value))
28 }
29
30 #[must_use]
31 pub fn value(self) -> u64 {
32 self.0
33 }
34
35 #[must_use]
39 pub fn next(self) -> Self {
40 Self(self.0.saturating_add(1))
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn zero_is_rejected() {
50 assert!(matches!(
51 GlobalPosition::new(0),
52 Err(DomainError::MustBeNonZero {
53 field: "global_position"
54 })
55 ));
56 }
57
58 #[test]
59 fn the_first_position_is_one_and_positions_advance_by_one() {
60 assert_eq!(GlobalPosition::FIRST.value(), 1);
61 assert_eq!(GlobalPosition::FIRST.next().value(), 2);
62 assert!(GlobalPosition::FIRST < GlobalPosition::FIRST.next());
63 }
64}