use super::super::ReplicaId;
use serde::{Deserialize, Serialize};
use std::fmt;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq)]
pub enum AdvancedCrdtError {
InvalidPosition(String),
ElementNotFound(String),
InvalidRelationship(String),
CycleDetected(String),
InvalidOperation(String),
MergeError(String),
}
impl fmt::Display for AdvancedCrdtError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AdvancedCrdtError::InvalidPosition(msg) => write!(f, "Invalid position: {}", msg),
AdvancedCrdtError::ElementNotFound(msg) => write!(f, "Element not found: {}", msg),
AdvancedCrdtError::InvalidRelationship(msg) => write!(f, "Invalid relationship: {}", msg),
AdvancedCrdtError::CycleDetected(msg) => write!(f, "Cycle detected: {}", msg),
AdvancedCrdtError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
AdvancedCrdtError::MergeError(msg) => write!(f, "Merge error: {}", msg),
}
}
}
impl std::error::Error for AdvancedCrdtError {}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct PositionId {
pub replica_id: ReplicaId,
pub timestamp: u64,
pub disambiguation: u64,
}
impl PositionId {
pub fn new(replica_id: ReplicaId, timestamp: u64, disambiguation: u64) -> Self {
Self {
replica_id,
timestamp,
disambiguation,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use super::super::super::ReplicaId;
use uuid::Uuid;
fn create_replica(id: u64) -> ReplicaId {
ReplicaId::from(Uuid::from_u64_pair(0, id))
}
#[test]
fn test_position_id_creation() {
let replica = create_replica(1);
let position = PositionId::new(replica, 12345, 67890);
assert_eq!(position.replica_id, replica);
assert_eq!(position.timestamp, 12345);
assert_eq!(position.disambiguation, 67890);
}
#[test]
fn test_position_id_ordering() {
let replica1 = create_replica(1);
let replica2 = create_replica(2);
let pos1 = PositionId::new(replica1, 100, 10);
let pos2 = PositionId::new(replica1, 200, 10);
let pos3 = PositionId::new(replica2, 100, 10);
assert!(pos1 < pos2);
assert!(pos1 < pos3);
assert!(pos2 > pos3);
}
#[test]
fn test_advanced_crdt_error_display() {
let error = AdvancedCrdtError::InvalidPosition("test".to_string());
assert_eq!(format!("{}", error), "Invalid position: test");
let error = AdvancedCrdtError::ElementNotFound("missing".to_string());
assert_eq!(format!("{}", error), "Element not found: missing");
}
}