use std::fmt;
use serde::{Deserialize, Serialize};
use url::Url;
use super::{ValidationError, Validator};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Tracker {
#[serde(default = "Tracker::default_api_url")]
pub api_url: Url,
#[serde(default = "Tracker::default_listed")]
pub listed: bool,
#[serde(default = "Tracker::default_private")]
pub private: bool,
#[serde(default = "Tracker::default_token")]
pub token: ApiToken,
#[serde(default = "Tracker::default_token_valid_seconds")]
pub token_valid_seconds: u64,
#[serde(default = "Tracker::default_url")]
pub url: Url,
}
impl Validator for Tracker {
fn validate(&self) -> Result<(), ValidationError> {
if self.private && (self.url.scheme() != "http" && self.url.scheme() != "https") {
return Err(ValidationError::UdpTrackersInPrivateModeNotSupported);
}
Ok(())
}
}
impl Default for Tracker {
fn default() -> Self {
Self {
url: Self::default_url(),
listed: Self::default_listed(),
private: Self::default_private(),
api_url: Self::default_api_url(),
token: Self::default_token(),
token_valid_seconds: Self::default_token_valid_seconds(),
}
}
}
impl Tracker {
pub fn override_tracker_api_token(&mut self, tracker_api_token: &ApiToken) {
self.token = tracker_api_token.clone();
}
fn default_url() -> Url {
Url::parse("udp://localhost:6969").unwrap()
}
fn default_listed() -> bool {
false
}
fn default_private() -> bool {
false
}
fn default_api_url() -> Url {
Url::parse("http://localhost:1212/").unwrap()
}
fn default_token() -> ApiToken {
ApiToken::new("MyAccessToken")
}
fn default_token_valid_seconds() -> u64 {
7_257_600
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ApiToken(String);
impl ApiToken {
#[must_use]
pub fn new(key: &str) -> Self {
assert!(!key.is_empty(), "tracker API token cannot be empty");
Self(key.to_owned())
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}
impl fmt::Display for ApiToken {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::ApiToken;
#[test]
#[should_panic(expected = "tracker API token cannot be empty")]
fn apai_token_can_not_be_empty() {
drop(ApiToken::new(""));
}
}