QuickDID is a high-performance AT Protocol identity resolution service written in Rust. It provides handle-to-DID resolution with Redis-backed caching and queue processing.
at main 4.4 kB view raw
1//! Work item types for queue processing. 2//! 3//! This module defines the various work item types that can be processed 4//! through the queue system, such as handle resolution requests. 5 6use serde::{Deserialize, Serialize}; 7 8/// Work item for handle resolution tasks. 9/// 10/// This structure represents a request to resolve an AT Protocol handle 11/// to its corresponding DID. It's the primary work type processed by 12/// the QuickDID service's background queue workers. 13/// 14/// # Examples 15/// 16/// ``` 17/// use quickdid::queue::HandleResolutionWork; 18/// 19/// let work = HandleResolutionWork::new("alice.bsky.social".to_string()); 20/// assert_eq!(work.handle, "alice.bsky.social"); 21/// ``` 22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] 23pub struct HandleResolutionWork { 24 /// The AT Protocol handle to resolve (e.g., "alice.bsky.social") 25 pub handle: String, 26} 27 28impl HandleResolutionWork { 29 /// Create a new handle resolution work item. 30 /// 31 /// # Arguments 32 /// 33 /// * `handle` - The AT Protocol handle to resolve 34 /// 35 /// # Examples 36 /// 37 /// ``` 38 /// use quickdid::queue::HandleResolutionWork; 39 /// 40 /// let work = HandleResolutionWork::new("alice.bsky.social".to_string()); 41 /// ``` 42 pub fn new(handle: String) -> Self { 43 Self { handle } 44 } 45} 46 47impl std::fmt::Display for HandleResolutionWork { 48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 49 write!(f, "HandleResolution({})", self.handle) 50 } 51} 52 53/// Trait for getting a unique deduplication key from a work item. 54/// This is used by the Redis queue adapter to prevent duplicate items. 55pub trait DedupKey { 56 /// Get a unique key for deduplication purposes. 57 /// This should return a consistent identifier for equivalent work items. 58 fn dedup_key(&self) -> String; 59} 60 61impl DedupKey for HandleResolutionWork { 62 fn dedup_key(&self) -> String { 63 // Use the handle itself as the dedup key 64 self.handle.clone() 65 } 66} 67 68// For testing purposes, implement DedupKey for String 69#[cfg(test)] 70impl DedupKey for String { 71 fn dedup_key(&self) -> String { 72 self.clone() 73 } 74} 75 76#[cfg(test)] 77mod tests { 78 use super::*; 79 80 #[test] 81 fn test_handle_resolution_work_creation() { 82 let handle = "alice.example.com"; 83 let work = HandleResolutionWork::new(handle.to_string()); 84 assert_eq!(work.handle, handle); 85 } 86 87 #[test] 88 fn test_handle_resolution_work_serialization() { 89 let work = HandleResolutionWork::new("bob.example.com".to_string()); 90 91 // Test JSON serialization (which is what we actually use in the queue adapters) 92 let json = serde_json::to_string(&work).expect("Failed to serialize to JSON"); 93 let deserialized: HandleResolutionWork = 94 serde_json::from_str(&json).expect("Failed to deserialize from JSON"); 95 assert_eq!(work, deserialized); 96 97 // Verify the JSON structure 98 let json_value: serde_json::Value = serde_json::from_str(&json).unwrap(); 99 assert_eq!(json_value["handle"], "bob.example.com"); 100 } 101 102 #[test] 103 fn test_handle_resolution_work_display() { 104 let work = HandleResolutionWork::new("charlie.example.com".to_string()); 105 let display = format!("{}", work); 106 assert_eq!(display, "HandleResolution(charlie.example.com)"); 107 } 108 109 #[test] 110 fn test_handle_resolution_work_equality() { 111 let work1 = HandleResolutionWork::new("alice.example.com".to_string()); 112 let work2 = HandleResolutionWork::new("alice.example.com".to_string()); 113 let work3 = HandleResolutionWork::new("bob.example.com".to_string()); 114 115 assert_eq!(work1, work2); 116 assert_ne!(work1, work3); 117 } 118 119 #[test] 120 fn test_handle_resolution_work_dedup_key() { 121 let work1 = HandleResolutionWork::new("alice.example.com".to_string()); 122 let work2 = HandleResolutionWork::new("alice.example.com".to_string()); 123 let work3 = HandleResolutionWork::new("bob.example.com".to_string()); 124 125 // Same handle should have same dedup key 126 assert_eq!(work1.dedup_key(), work2.dedup_key()); 127 assert_eq!(work1.dedup_key(), "alice.example.com"); 128 129 // Different handle should have different dedup key 130 assert_ne!(work1.dedup_key(), work3.dedup_key()); 131 assert_eq!(work3.dedup_key(), "bob.example.com"); 132 } 133}