use super::super::{CRDT, Mergeable, ReplicaId};
use serde::{Deserialize, Serialize};
use std::error::Error;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GraphError {
message: String,
}
impl GraphError {
pub fn new(message: String) -> Self {
Self { message }
}
}
impl std::fmt::Display for GraphError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "GraphError: {}", self.message)
}
}
impl Error for GraphError {}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct VertexId {
pub id: Uuid,
pub replica: ReplicaId,
}
impl VertexId {
pub fn new(replica: ReplicaId) -> Self {
Self {
id: Uuid::new_v4(),
replica,
}
}
pub fn from_parts(id: Uuid, replica: ReplicaId) -> Self {
Self { id, replica }
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct VertexMetadata {
pub created_at: u64,
pub modified_at: u64,
pub deleted: bool,
pub last_modified_by: ReplicaId,
}
impl VertexMetadata {
pub fn new(replica: ReplicaId, timestamp: u64) -> Self {
Self {
created_at: timestamp,
modified_at: timestamp,
deleted: false,
last_modified_by: replica,
}
}
pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
self.modified_at = timestamp;
self.last_modified_by = replica;
}
pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
self.deleted = true;
self.mark_modified(replica, timestamp);
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Vertex<T> {
pub id: VertexId,
pub value: T,
pub metadata: VertexMetadata,
}
impl<T> Vertex<T> {
pub fn new(value: T, replica: ReplicaId, timestamp: u64) -> Self {
Self {
id: VertexId::new(replica),
value,
metadata: VertexMetadata::new(replica, timestamp),
}
}
pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
self.metadata.mark_modified(replica, timestamp);
}
pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
self.metadata.mark_deleted(replica, timestamp);
}
}
#[cfg(test)]
mod tests {
use super::super::super::ReplicaId;
use super::*;
use uuid::Uuid;
fn create_replica(id: u64) -> ReplicaId {
ReplicaId::from(Uuid::from_u64_pair(0, id))
}
#[test]
fn test_vertex_id_creation() {
let replica = create_replica(1);
let vertex_id = VertexId::new(replica);
assert_eq!(vertex_id.replica, replica);
assert_ne!(vertex_id.id, Uuid::nil());
}
#[test]
fn test_vertex_creation() {
let replica = create_replica(1);
let timestamp = 1234567890;
let vertex = Vertex::new("test_value", replica, timestamp);
assert_eq!(vertex.value, "test_value");
assert_eq!(vertex.metadata.created_at, timestamp);
assert_eq!(vertex.metadata.modified_at, timestamp);
assert_eq!(vertex.metadata.deleted, false);
assert_eq!(vertex.metadata.last_modified_by, replica);
}
#[test]
fn test_vertex_metadata_operations() {
let replica = create_replica(1);
let timestamp = 1234567890;
let mut metadata = VertexMetadata::new(replica, timestamp);
let new_timestamp = 1234567891;
metadata.mark_modified(replica, new_timestamp);
assert_eq!(metadata.modified_at, new_timestamp);
let delete_timestamp = 1234567892;
metadata.mark_deleted(replica, delete_timestamp);
assert_eq!(metadata.deleted, true);
assert_eq!(metadata.modified_at, delete_timestamp);
}
}