1use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub enum Region {
30 US,
32 EU,
34 CN,
36 KR,
38 TW,
40 SG,
42}
43
44impl Region {
45 #[must_use]
47 pub fn hostname(&self) -> &'static str {
48 match self {
49 Region::US => "us.version.battle.net",
50 Region::EU => "eu.version.battle.net",
51 Region::CN => "cn.version.battle.net",
52 Region::KR => "kr.version.battle.net",
53 Region::TW => "tw.version.battle.net",
54 Region::SG => "sg.version.battle.net",
55 }
56 }
57
58 #[must_use]
60 pub fn as_str(&self) -> &'static str {
61 match self {
62 Region::US => "us",
63 Region::EU => "eu",
64 Region::CN => "cn",
65 Region::KR => "kr",
66 Region::TW => "tw",
67 Region::SG => "sg",
68 }
69 }
70}
71
72impl fmt::Display for Region {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 write!(f, "{}", self.as_str())
75 }
76}
77
78impl std::str::FromStr for Region {
79 type Err = crate::error::Error;
80
81 fn from_str(s: &str) -> Result<Self, Self::Err> {
82 match s.to_lowercase().as_str() {
83 "us" => Ok(Region::US),
84 "eu" => Ok(Region::EU),
85 "cn" => Ok(Region::CN),
86 "kr" => Ok(Region::KR),
87 "tw" => Ok(Region::TW),
88 "sg" => Ok(Region::SG),
89 _ => Err(crate::error::Error::InvalidRegion(s.to_string())),
90 }
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum ProtocolVersion {
107 V1,
109 V2,
111}
112
113impl ProtocolVersion {
114 #[must_use]
116 pub fn prefix(&self) -> &'static str {
117 match self {
118 ProtocolVersion::V1 => "v1",
119 ProtocolVersion::V2 => "v2",
120 }
121 }
122}
123
124impl fmt::Display for ProtocolVersion {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 write!(f, "{}", self.prefix())
127 }
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
150pub enum Endpoint {
151 Summary,
153 ProductVersions(String),
155 ProductCdns(String),
157 ProductBgdl(String),
159 Cert(String),
161 Ocsp(String),
163 Custom(String),
165}
166
167impl Endpoint {
168 #[must_use]
170 pub fn as_path(&self) -> String {
171 match self {
172 Endpoint::Summary => "summary".to_string(),
173 Endpoint::ProductVersions(product) => format!("products/{product}/versions"),
174 Endpoint::ProductCdns(product) => format!("products/{product}/cdns"),
175 Endpoint::ProductBgdl(product) => format!("products/{product}/bgdl"),
176 Endpoint::Cert(hash) => format!("certs/{hash}"),
177 Endpoint::Ocsp(hash) => format!("ocsp/{hash}"),
178 Endpoint::Custom(path) => path.clone(),
179 }
180 }
181}
182
183pub const RIBBIT_PORT: u16 = 1119;
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn test_region_hostname() {
192 assert_eq!(Region::US.hostname(), "us.version.battle.net");
193 assert_eq!(Region::EU.hostname(), "eu.version.battle.net");
194 assert_eq!(Region::CN.hostname(), "cn.version.battle.net");
195 assert_eq!(Region::KR.hostname(), "kr.version.battle.net");
196 assert_eq!(Region::TW.hostname(), "tw.version.battle.net");
197 assert_eq!(Region::SG.hostname(), "sg.version.battle.net");
198 }
199
200 #[test]
201 fn test_region_as_str() {
202 assert_eq!(Region::US.as_str(), "us");
203 assert_eq!(Region::EU.as_str(), "eu");
204 assert_eq!(Region::CN.as_str(), "cn");
205 assert_eq!(Region::KR.as_str(), "kr");
206 assert_eq!(Region::TW.as_str(), "tw");
207 assert_eq!(Region::SG.as_str(), "sg");
208 }
209
210 #[test]
211 fn test_region_display() {
212 assert_eq!(Region::US.to_string(), "us");
213 assert_eq!(Region::EU.to_string(), "eu");
214 }
215
216 #[test]
217 fn test_region_from_str() {
218 assert_eq!("us".parse::<Region>().unwrap(), Region::US);
219 assert_eq!("US".parse::<Region>().unwrap(), Region::US);
220 assert_eq!("eu".parse::<Region>().unwrap(), Region::EU);
221 assert_eq!("EU".parse::<Region>().unwrap(), Region::EU);
222
223 assert!("invalid".parse::<Region>().is_err());
224 assert!("".parse::<Region>().is_err());
225 }
226
227 #[test]
228 fn test_protocol_version_prefix() {
229 assert_eq!(ProtocolVersion::V1.prefix(), "v1");
230 assert_eq!(ProtocolVersion::V2.prefix(), "v2");
231 }
232
233 #[test]
234 fn test_protocol_version_display() {
235 assert_eq!(ProtocolVersion::V1.to_string(), "v1");
236 assert_eq!(ProtocolVersion::V2.to_string(), "v2");
237 }
238
239 #[test]
240 fn test_endpoint_as_path() {
241 assert_eq!(Endpoint::Summary.as_path(), "summary");
242 assert_eq!(
243 Endpoint::ProductVersions("wow".to_string()).as_path(),
244 "products/wow/versions"
245 );
246 assert_eq!(
247 Endpoint::ProductCdns("wow_classic".to_string()).as_path(),
248 "products/wow_classic/cdns"
249 );
250 assert_eq!(
251 Endpoint::ProductBgdl("wow_beta".to_string()).as_path(),
252 "products/wow_beta/bgdl"
253 );
254 assert_eq!(
255 Endpoint::Cert("abc123".to_string()).as_path(),
256 "certs/abc123"
257 );
258 assert_eq!(
259 Endpoint::Ocsp("def456".to_string()).as_path(),
260 "ocsp/def456"
261 );
262 assert_eq!(
263 Endpoint::Custom("custom/path".to_string()).as_path(),
264 "custom/path"
265 );
266 }
267
268 #[test]
269 fn test_ribbit_port() {
270 assert_eq!(RIBBIT_PORT, 1119);
271 }
272}