use crate::structs::{Library, Shelf}; use std::{ fs, io::{self, Write}, path::Path, }; use xdg::BaseDirectories; pub fn prompt(text: &str) -> Result { print!("{} ", text); std::io::stdout().flush()?; let mut response = String::new(); std::io::stdin().read_line(&mut response); Ok(response.trim_end().to_owned()) } pub fn get_shelf_index(shelves: &Vec, id: &u8) -> Option { shelves.iter().position(|shelf| shelf.id == *id) } pub fn deserialize_state_file() -> io::Result { let xdg_dirs = get_xdg(); let state_file_path = xdg_dirs.place_state_file("shelf-state.json")?; let state_file_content = match fs::read_to_string(state_file_path) { Ok(content) => content, Err(e) => { eprintln!("Could not read state file: {}", e); return Ok(initialize_library()); } }; let state_file_decoded: Library = serde_json::from_str(&state_file_content)?; Ok(state_file_decoded) } pub fn get_xdg() -> BaseDirectories { let xdg_dirs = xdg::BaseDirectories::with_prefix("shelf"); return xdg_dirs; } pub fn get_state_file() -> io::Result { let xdg_dirs = get_xdg(); let state_file_path = xdg_dirs.place_state_file("shelf-state.json")?; Ok(state_file_path) } pub fn save_library(library: Library) -> io::Result<()> { let seralized_library = serde_json::to_string(&library).unwrap_or_default(); let state_file = get_state_file()?; fs::write(state_file, seralized_library)?; Ok(()) } pub fn get_current_shelf(library: &mut Library) -> &mut Shelf { // Rust variable nonsense (get current shelf index) let shelves = &library.shelves; let current_shelf = &library.current_shelf; let shelf_index = get_shelf_index(shelves, current_shelf).unwrap_or(0); // Get current shelf index and push the file let current_shelf = &mut library.shelves[*&shelf_index]; current_shelf.content.sort(); current_shelf.content.dedup(); return current_shelf; } pub fn initialize_library() -> Library { let default_shelf: Shelf = Shelf { id: 0, name: "default".to_string(), content: Vec::new(), }; let mut shelf_vec: Vec = Vec::new(); shelf_vec.push(default_shelf); let default_library: Library = Library { current_shelf: 0, shelves: shelf_vec, }; return default_library; } pub fn match_file_name(file_name: &str, shelf: &mut Shelf) -> Result { // Turn given file into string let match_path = Path::new(file_name); // Check if there is a match in the shelf before taking the path verbatim let file_ending = match_path.file_name().expect("Error getting file name"); // For every entry in current shelf for (i, path) in shelf.content.iter().enumerate() { // Turn the string back into a path let shelf_path = Path::new(path).canonicalize()?; if shelf_path.ends_with(file_ending) { return Ok(i); }; } if match_path.exists() { let cannonical_path = match_path.canonicalize()?; for (i, path) in shelf.content.iter().enumerate() { let shelf_path = Path::new(path).canonicalize()?; if cannonical_path == shelf_path { return Ok(i); } } } Err(io::Error::new( io::ErrorKind::NotFound, format!("File not Found in Shelf \"{}\": {file_name}", shelf.name), )) }