1use std::fmt;
2
3#[derive(Clone, Debug, Eq, PartialEq)]
4pub enum ClientId {
5 SolanaLabs,
6 JitoLabs,
7 Frankendancer,
8 Agave,
9 AgavePaladin,
10 Firedancer,
11 AgaveBam,
12 Sig,
13 Rakurai,
14 HarmonicFiredancer,
15 HarmonicAgave,
16 HarmonicFrankendancer,
17 FireBAM,
18 Raiku,
19 Unknown(u16),
21}
22
23impl fmt::Display for ClientId {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 match self {
26 Self::SolanaLabs => write!(f, "SolanaLabs"),
27 Self::JitoLabs => write!(f, "JitoLabs"),
28 Self::Frankendancer => write!(f, "Frankendancer"),
29 Self::Agave => write!(f, "Agave"),
30 Self::AgavePaladin => write!(f, "AgavePaladin"),
31 Self::Firedancer => write!(f, "Firedancer"),
32 Self::AgaveBam => write!(f, "AgaveBam"),
33 Self::Sig => write!(f, "Sig"),
34 Self::Rakurai => write!(f, "Rakurai"),
35 Self::HarmonicFiredancer => write!(f, "HarmonicFiredancer"),
36 Self::HarmonicAgave => write!(f, "HarmonicAgave"),
37 Self::HarmonicFrankendancer => write!(f, "HarmonicFrankendancer"),
38 Self::FireBAM => write!(f, "FireBAM"),
39 Self::Raiku => write!(f, "Raiku"),
40 Self::Unknown(id) => write!(f, "Unknown({id})"),
41 }
42 }
43}
44
45impl From<u16> for ClientId {
46 fn from(client: u16) -> Self {
47 match client {
48 0u16 => Self::SolanaLabs,
49 1u16 => Self::JitoLabs,
50 2u16 => Self::Frankendancer,
51 3u16 => Self::Agave,
52 4u16 => Self::AgavePaladin,
53 5u16 => Self::Firedancer,
54 6u16 => Self::AgaveBam,
55 7u16 => Self::Sig,
56 8u16 => Self::Rakurai,
57 9u16 => Self::HarmonicFiredancer,
58 10u16 => Self::HarmonicAgave,
59 11u16 => Self::HarmonicFrankendancer,
60 12u16 => Self::FireBAM,
61 13u16 => Self::Raiku,
62 _ => Self::Unknown(client),
63 }
64 }
65}
66
67impl TryFrom<ClientId> for u16 {
68 type Error = String;
69
70 fn try_from(client: ClientId) -> Result<Self, Self::Error> {
71 match client {
72 ClientId::SolanaLabs => Ok(0u16),
73 ClientId::JitoLabs => Ok(1u16),
74 ClientId::Frankendancer => Ok(2u16),
75 ClientId::Agave => Ok(3u16),
76 ClientId::AgavePaladin => Ok(4u16),
77 ClientId::Firedancer => Ok(5u16),
78 ClientId::AgaveBam => Ok(6u16),
79 ClientId::Sig => Ok(7u16),
80 ClientId::Rakurai => Ok(8u16),
81 ClientId::HarmonicFiredancer => Ok(9u16),
82 ClientId::HarmonicAgave => Ok(10u16),
83 ClientId::HarmonicFrankendancer => Ok(11u16),
84 ClientId::FireBAM => Ok(12u16),
85 ClientId::Raiku => Ok(13u16),
86 ClientId::Unknown(client @ 0u16..=13u16) => Err(format!("Invalid client: {client}")),
87 ClientId::Unknown(client) => Ok(client),
88 }
89 }
90}
91
92impl ClientId {
93 pub const fn this_client() -> Self {
94 Self::Agave
96 }
97}
98
99#[cfg(test)]
100mod test {
101 use super::*;
102
103 #[test]
104 fn test_client_id() {
105 assert_eq!(ClientId::from(0u16), ClientId::SolanaLabs);
106 assert_eq!(ClientId::from(1u16), ClientId::JitoLabs);
107 assert_eq!(ClientId::from(2u16), ClientId::Frankendancer);
108 assert_eq!(ClientId::from(3u16), ClientId::Agave);
109 assert_eq!(ClientId::from(4u16), ClientId::AgavePaladin);
110 assert_eq!(ClientId::from(5u16), ClientId::Firedancer);
111 assert_eq!(ClientId::from(6u16), ClientId::AgaveBam);
112 assert_eq!(ClientId::from(7u16), ClientId::Sig);
113 assert_eq!(ClientId::from(8u16), ClientId::Rakurai);
114 assert_eq!(ClientId::from(9u16), ClientId::HarmonicFiredancer);
115 assert_eq!(ClientId::from(10u16), ClientId::HarmonicAgave);
116 assert_eq!(ClientId::from(11u16), ClientId::HarmonicFrankendancer);
117 assert_eq!(ClientId::from(12u16), ClientId::FireBAM);
118 assert_eq!(ClientId::from(13u16), ClientId::Raiku);
119 for client in 14u16..=u16::MAX {
120 assert_eq!(ClientId::from(client), ClientId::Unknown(client));
121 }
122 assert_eq!(u16::try_from(ClientId::SolanaLabs), Ok(0u16));
123 assert_eq!(u16::try_from(ClientId::JitoLabs), Ok(1u16));
124 assert_eq!(u16::try_from(ClientId::Frankendancer), Ok(2u16));
125 assert_eq!(u16::try_from(ClientId::Agave), Ok(3u16));
126 assert_eq!(u16::try_from(ClientId::AgavePaladin), Ok(4u16));
127 assert_eq!(u16::try_from(ClientId::Firedancer), Ok(5u16));
128 assert_eq!(u16::try_from(ClientId::AgaveBam), Ok(6u16));
129 assert_eq!(u16::try_from(ClientId::Sig), Ok(7u16));
130 assert_eq!(u16::try_from(ClientId::Rakurai), Ok(8u16));
131 assert_eq!(u16::try_from(ClientId::HarmonicFiredancer), Ok(9u16));
132 assert_eq!(u16::try_from(ClientId::HarmonicAgave), Ok(10u16));
133 assert_eq!(u16::try_from(ClientId::HarmonicFrankendancer), Ok(11u16));
134 assert_eq!(u16::try_from(ClientId::FireBAM), Ok(12u16));
135 assert_eq!(u16::try_from(ClientId::Raiku), Ok(13u16));
136
137 for client in 0..=13u16 {
138 assert_eq!(
139 u16::try_from(ClientId::Unknown(client)),
140 Err(format!("Invalid client: {client}"))
141 );
142 }
143 for client in 14u16..=u16::MAX {
144 assert_eq!(u16::try_from(ClientId::Unknown(client)), Ok(client));
145 }
146 }
147
148 #[test]
149 fn test_fmt() {
150 assert_eq!(format!("{}", ClientId::SolanaLabs), "SolanaLabs");
151 assert_eq!(format!("{}", ClientId::JitoLabs), "JitoLabs");
152 assert_eq!(format!("{}", ClientId::Frankendancer), "Frankendancer");
153 assert_eq!(format!("{}", ClientId::Agave), "Agave");
154 assert_eq!(format!("{}", ClientId::AgavePaladin), "AgavePaladin");
155 assert_eq!(format!("{}", ClientId::Firedancer), "Firedancer");
156 assert_eq!(format!("{}", ClientId::AgaveBam), "AgaveBam");
157 assert_eq!(format!("{}", ClientId::Sig), "Sig");
158 assert_eq!(format!("{}", ClientId::Rakurai), "Rakurai");
159 assert_eq!(
160 format!("{}", ClientId::HarmonicFiredancer),
161 "HarmonicFiredancer"
162 );
163 assert_eq!(format!("{}", ClientId::HarmonicAgave), "HarmonicAgave");
164 assert_eq!(
165 format!("{}", ClientId::HarmonicFrankendancer),
166 "HarmonicFrankendancer"
167 );
168 assert_eq!(format!("{}", ClientId::FireBAM), "FireBAM");
169 assert_eq!(format!("{}", ClientId::Raiku), "Raiku");
170 assert_eq!(format!("{}", ClientId::Unknown(0)), "Unknown(0)");
171 assert_eq!(format!("{}", ClientId::Unknown(u16::MAX)), "Unknown(65535)");
172 }
173}