use std::{ collections::HashMap, fs::File, io::{BufRead, BufReader}, path::PathBuf, }; #[derive(Debug)] pub struct Config { pub pictures_dir: Option, pub videos_dir: Option, pub music_dir: Option, pub books_dir: Option, pub sources: HashMap, } pub const PICTURE_EXTENTIONS: [&str; 17] = [ "jpg", "jpeg", "png", "gif", "webp", "jfif", "bmp", "apng", "avif", "tif", "tga", "psd", "eps", "ai", "indd", "raw", "ico", ]; pub const SOUND_EXTENTIONS: [&str; 10] = [ "mp3", "wav", "flac", "ogg", "aac", "m4a", "wma", "aiff", "au", "opus", ]; pub const BOOK_EXTENTIONS: [&str; 11] = [ "pdf", "epub", "mobi", "cbz", "cbr", "chm", "djvu", "fb2", "lit", "prc", "xps", ]; pub const VIDEO_EXTENTIONS: [&str; 11] = [ "mp4", "mkv", "avi", "flv", "webm", "wmv", "mov", "m4v", "3gp", "3g2", "swf", ]; impl Config { pub fn parse(path: PathBuf) -> Result> { let mut sources: HashMap = HashMap::new(); let mut pictures_dir = None; let mut videos_dir = None; let mut music_dir = None; let mut books_dir = None; let config_file = File::open(path)?; let reader = BufReader::new(config_file); let mut current_section = String::new(); for line in reader .lines() .map_while(Result::ok) .map(|l| String::from(l.trim())) .filter(|l| !l.is_empty()) .filter(|l| !l.starts_with('#')) { if line.starts_with('[') && line.contains(']') { current_section = line[1..line.find(']').unwrap()].to_string(); } else if let Some((key, value)) = line.split_once('=') { let key_trimmed_string = key.trim().replace('"', ""); let key_trimmed = key_trimmed_string.as_str(); let value_trimmed_string = value.trim().replace('"', ""); let value_trimmed = value_trimmed_string.as_str(); match current_section.as_str() { "sources" => { sources.insert(key_trimmed.into(), value_trimmed.into()); } "destinations" => match key_trimmed { "music_dir" => music_dir = Some(PathBuf::from(value_trimmed)), "video_dir" => videos_dir = Some(PathBuf::from(value_trimmed)), "books_dir" => books_dir = Some(PathBuf::from(value_trimmed)), "pictures_dir" => pictures_dir = Some(PathBuf::from(value_trimmed)), _ => {} }, _ => {} } } } Ok(Self { pictures_dir, videos_dir, music_dir, books_dir, sources, }) } pub fn create(path: &PathBuf) -> Result<(), Box> { let config_str = r#" [destinations] pictures_dir = "" videos_dir = "" music_dir = "" books_dir = "" [sources] # Put your own sources there like so: # "Source Name" = "path" "#; std::fs::write(path, config_str)?; Ok(()) } }