nntp_proxy/
types.rs

1//! Core types for request tracking and identification
2//!
3//! This module provides unique identifiers used throughout the proxy.
4
5use uuid::Uuid;
6
7/// Unique identifier for client connections
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct ClientId(Uuid);
10
11impl ClientId {
12    /// Generate a new unique client ID
13    #[must_use]
14    pub fn new() -> Self {
15        Self(Uuid::new_v4())
16    }
17}
18
19impl Default for ClientId {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl std::fmt::Display for ClientId {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        write!(f, "{}", self.0)
28    }
29}
30
31/// Identifier for backend servers
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
33pub struct BackendId(usize);
34
35impl BackendId {
36    /// Create a backend ID from an index
37    /// Marked const fn to allow compile-time evaluation
38    #[must_use]
39    #[inline]
40    pub const fn from_index(index: usize) -> Self {
41        Self(index)
42    }
43
44    /// Get the underlying index
45    #[must_use]
46    #[inline]
47    pub fn as_index(&self) -> usize {
48        self.0
49    }
50}
51
52impl From<usize> for BackendId {
53    fn from(index: usize) -> Self {
54        Self(index)
55    }
56}
57
58impl std::fmt::Display for BackendId {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(f, "Backend({})", self.0)
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_client_id_unique() {
70        let id1 = ClientId::new();
71        let id2 = ClientId::new();
72        assert_ne!(id1, id2);
73    }
74
75    #[test]
76    fn test_backend_id() {
77        let id1 = BackendId::from_index(0);
78        let id2 = BackendId::from_index(1);
79        assert_ne!(id1, id2);
80        assert_eq!(id1.as_index(), 0);
81        assert_eq!(id2.as_index(), 1);
82    }
83
84    #[test]
85    fn test_display() {
86        let client_id = ClientId::new();
87        let backend_id = BackendId::from_index(5);
88
89        assert!(!format!("{}", client_id).is_empty());
90        assert_eq!(format!("{}", backend_id), "Backend(5)");
91    }
92}