use serde::{Deserialize, Serialize}; use std::fs; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum StationStatus { Online, Offline, Receive, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StationId(pub String); #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Station { pub id: StationId, pub name: String, pub host: String, pub port: i32, pub url: Option, pub status: StationStatus, pub location: Option, pub genre: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Server { pub address: String, pub port: i32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { pub server: Server, pub stations: Option>, } impl Config { pub fn new() -> Self { Config::default() } pub fn open(path: &std::path::Path) -> Result { fs::read_to_string(path)?.parse() } pub fn data_dir() -> Result { let cwd = std::env::current_dir()?; if cfg!(debug_assertions) { Ok(cwd.join("temp")) } else { Ok(cwd) } } pub fn to_string(&self) -> Result { Ok(toml::to_string(self)?) } pub fn write(&self, path: &std::path::Path) -> Result<(), ConfigError> { Ok(fs::write(path, self.to_string()?)?) } } impl Default for Config { fn default() -> Self { Config { server: Server { address: String::from("127.0.0.1"), port: 54605, }, stations: None, } } } impl std::str::FromStr for Config { type Err = ConfigError; fn from_str(s: &str) -> Result { toml::from_str(s).map_err(|_| ConfigError::Parse) } } #[derive(Debug)] pub enum ConfigError { Parse, StringParse, Serialize, IO, } impl std::error::Error for ConfigError {} impl std::fmt::Display for ConfigError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Self::Parse => write!(f, "Failed to parse Config from string"), Self::StringParse => write!(f, "Failed to parse environment variable"), Self::Serialize => write!(f, "Failed to serialize Config to TOML"), Self::IO => write!(f, "Faild to write file"), } } } impl From for ConfigError { fn from(_: toml::ser::Error) -> Self { ConfigError::Serialize } } impl From for ConfigError { fn from(_: std::io::Error) -> Self { ConfigError::IO } } impl From for ConfigError { fn from(_: std::num::ParseIntError) -> Self { ConfigError::StringParse } }