use crate::config_check::{ConfigCheck, ConfigCheckError, EmptyFieldError};
use gethostname::gethostname;
use serde::{Deserialize, Serialize};
use url::Url;
const DEFAULT_NAME: &str = "computer";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LocalHostOptions {
pub name: String,
pub description: String,
pub urls: Vec<String>,
}
impl LocalHostOptions {
pub fn new() -> LocalHostOptions {
Self::default()
}
pub fn with_name(&self, name: &str) -> LocalHostOptions {
match self.try_with_name(name) {
Ok(updated) => updated,
Err(_) => {
let mut updated = self.clone();
updated.name = Self::get_default_name();
updated
}
}
}
pub fn try_with_name(&self, name: &str) -> Result<LocalHostOptions, ConfigCheckError> {
let mut updated = self.clone();
updated.name = String::from(name);
updated.check()?;
Ok(updated)
}
pub fn with_description(&self, description: &str) -> LocalHostOptions {
self.try_with_description(description)
.unwrap_or(self.clone())
}
pub fn try_with_description(
&self,
description: &str,
) -> Result<LocalHostOptions, ConfigCheckError> {
let mut updated = self.clone();
updated.description = String::from(description);
updated.check()?;
Ok(updated)
}
pub fn with_urls(&self, urls: &Vec<&str>) -> LocalHostOptions {
self.try_with_urls(urls).unwrap_or(self.clone())
}
pub fn try_with_urls(&self, urls: &Vec<&str>) -> Result<LocalHostOptions, ConfigCheckError> {
let mut updated = self.clone();
let mut valid_urls: Vec<String> = Vec::new();
for url in urls.iter() {
match Url::parse(url) {
Ok(_) => {
valid_urls.push(String::from(*url));
}
Err(e) => return Err(ConfigCheckError::Parse(e)),
}
}
updated.urls = valid_urls;
updated.check()?;
Ok(updated)
}
fn get_default_name() -> String {
match gethostname().to_str() {
Some(hostname) => {
if hostname.len() > 0 {
hostname
} else {
DEFAULT_NAME
}
}
None => DEFAULT_NAME,
}
.to_string()
}
}
impl ConfigCheck for LocalHostOptions {
fn check(&self) -> Result<LocalHostOptions, ConfigCheckError> {
if self.name.len() == 0 {
return Err(ConfigCheckError::Empty(EmptyFieldError::new("name")));
}
for url in self.urls.iter() {
match Url::parse(url) {
Ok(_) => {}
Err(e) => return Err(ConfigCheckError::Parse(e)),
}
}
Ok(self.clone())
}
}
impl std::default::Default for LocalHostOptions {
fn default() -> LocalHostOptions {
LocalHostOptions {
name: Self::get_default_name(),
description: String::new(),
urls: Vec::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::LocalHostOptions;
use gethostname::gethostname;
use serde_json;
#[test]
fn test_local_host_options_serde_json() {
let options = LocalHostOptions::new();
let serialized = serde_json::to_string(&options).unwrap();
assert_eq!(
format!(
"{{\"name\":\"{}\",\"description\":\"\",\"urls\":[]}}",
gethostname().to_str().unwrap()
),
serialized
);
}
}