torrust_index/config/v2/
tracker.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4use url::Url;
5
6use super::{ValidationError, Validator};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10pub struct Tracker {
11 #[serde(default = "Tracker::default_api_url")]
13 pub api_url: Url,
14
15 #[serde(default = "Tracker::default_listed")]
17 pub listed: bool,
18
19 #[serde(default = "Tracker::default_private")]
21 pub private: bool,
22
23 #[serde(default = "Tracker::default_token")]
25 pub token: ApiToken,
26
27 #[serde(default = "Tracker::default_token_valid_seconds")]
29 pub token_valid_seconds: u64,
30
31 #[serde(default = "Tracker::default_url")]
33 pub url: Url,
34}
35
36impl Validator for Tracker {
37 fn validate(&self) -> Result<(), ValidationError> {
38 if self.private && (self.url.scheme() != "http" && self.url.scheme() != "https") {
39 return Err(ValidationError::UdpTrackersInPrivateModeNotSupported);
40 }
41
42 Ok(())
43 }
44}
45
46impl Default for Tracker {
47 fn default() -> Self {
48 Self {
49 url: Self::default_url(),
50 listed: Self::default_listed(),
51 private: Self::default_private(),
52 api_url: Self::default_api_url(),
53 token: Self::default_token(),
54 token_valid_seconds: Self::default_token_valid_seconds(),
55 }
56 }
57}
58
59impl Tracker {
60 pub fn override_tracker_api_token(&mut self, tracker_api_token: &ApiToken) {
61 self.token = tracker_api_token.clone();
62 }
63
64 fn default_url() -> Url {
65 Url::parse("udp://localhost:6969").unwrap()
66 }
67
68 fn default_listed() -> bool {
69 false
70 }
71
72 fn default_private() -> bool {
73 false
74 }
75
76 fn default_api_url() -> Url {
77 Url::parse("http://localhost:1212/").unwrap()
78 }
79
80 fn default_token() -> ApiToken {
81 ApiToken::new("MyAccessToken")
82 }
83
84 fn default_token_valid_seconds() -> u64 {
85 7_257_600
86 }
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
90pub struct ApiToken(String);
91
92impl ApiToken {
93 #[must_use]
97 pub fn new(key: &str) -> Self {
98 assert!(!key.is_empty(), "tracker API token cannot be empty");
99
100 Self(key.to_owned())
101 }
102
103 #[must_use]
104 pub fn as_bytes(&self) -> &[u8] {
105 self.0.as_bytes()
106 }
107}
108
109impl fmt::Display for ApiToken {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(f, "{}", self.0)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::ApiToken;
118
119 #[test]
120 #[should_panic(expected = "tracker API token cannot be empty")]
121 fn apai_token_can_not_be_empty() {
122 drop(ApiToken::new(""));
123 }
124}