use serde::{Deserialize, Serialize}; use std::{ error::Error, fs::{read_to_string, write}, }; // General configuration Struct #[derive(Debug, Deserialize, Serialize)] pub struct Config { pub peertube: PeertubeConfig, pub youtube: YoutubeConfig, #[serde(default)] pub tootube: TootubeConfig, } #[derive(Debug, Deserialize, Serialize)] pub struct PeertubeConfig { pub base_url: String, #[serde(default)] pub delete_video_source_after_transfer: bool, pub oauth2: Option, } impl Default for PeertubeConfig { fn default() -> Self { PeertubeConfig { base_url: "".to_string(), delete_video_source_after_transfer: false, oauth2: None, } } } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct PeertubeConfigOauth2 { pub client_id: String, pub client_secret: String, pub refresh_token: String, } #[derive(Debug, Deserialize, Serialize)] pub struct YoutubeConfig { #[serde(default)] pub notify_subscribers_on_shorts: bool, pub oauth2: YoutubeConfigOauth2, } #[derive(Debug, Deserialize, Serialize)] pub struct YoutubeConfigOauth2 { pub refresh_token: String, pub client_id: String, pub client_secret: String, } #[derive(Debug, Deserialize, Serialize)] pub struct TootubeConfig { pub progress_bar: String, pub progress_chars: String, } impl Default for TootubeConfig { fn default() -> Self { TootubeConfig { progress_bar: "{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})".to_string(), progress_chars: "#>-".to_string(), } } } impl Config { /// Parses the TOML file into a Config struct pub fn new(toml_file: &str) -> Self { let toml_config = read_to_string(toml_file) .unwrap_or_else(|e| panic!("Cannot open file {toml_file}: {e}")); let config: Config = toml::from_str(&toml_config) .unwrap_or_else(|e| panic!("Cannot parse TOML file {toml_file}: {e}")); config } pub fn dump(&mut self, toml_file: &str) -> Result<(), Box> { // bring back the default for progress bar self.tootube = TootubeConfig::default(); write(toml_file, toml::to_string_pretty(self)?)?; Ok(()) } } #[cfg(test)] mod tests { use super::*; use std::fs::{remove_file, write}; #[test] fn test_minimal_conf() { let file_name = "/tmp/test_minimal_conf.toml"; let data = r#" [peertube] base_url = 'https://p.nintendojo.fr' [youtube.oauth2] refresh_token = 'rt_N/A' client_id = 'ci_N/A' client_secret = 'cs_N/A' "#; write(file_name, data).unwrap(); let config = Config::new(file_name); assert_eq!(config.youtube.notify_subscribers_on_shorts, false); assert_eq!(config.tootube.progress_chars, "#>-"); assert_eq!(config.youtube.oauth2.refresh_token, "rt_N/A"); assert_eq!(config.youtube.oauth2.client_id, "ci_N/A"); assert_eq!(config.youtube.oauth2.client_secret, "cs_N/A"); remove_file(file_name).unwrap(); } }