nntp_proxy/
types.rs

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