use crate::configuration::Configuration; use std::fmt::Write; use std::fs; use std::io::{Error, Result}; use std::path::PathBuf; pub fn status(configuration: &Configuration) -> Result { let mut status_message = String::new(); status_message.push_str("# Configuration\n"); status_message.push_str("\n## Directories\n"); // Main Configuration Locations status_message.push_str(&get_directory_stats( "Configuration", &configuration.config_directory, )?); status_message.push_str(&get_directory_stats("Data", &configuration.data_directory)?); status_message.push_str(&get_directory_stats( "Output", &configuration.output_directory, )?); status_message.push_str("\n## Blog Settings\n"); writeln!( &mut status_message, "Number of posts to keep: {}", configuration.max_posts ) .map_err(|_| Error::other("Unable to write status"))?; Ok(status_message) } fn get_directory_stats(label: &str, directory: &PathBuf) -> Result { let mut status_message = String::new(); write!(&mut status_message, "{}: {}. ", label, directory.display()) .map_err(|_| Error::other("Unable to write status"))?; if directory.exists() { status_message.push_str("Exists "); if fs::read_dir(directory).is_ok() { status_message.push_str("and is readable.\n"); } else { status_message.push_str("but is not readable.\n"); } } else { status_message.push_str("Does not exist.\n"); } Ok(status_message) } #[cfg(test)] mod tests { use std::fs::{metadata, set_permissions}; use std::path::PathBuf; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; #[cfg(windows)] use std::os::windows::fs::PermissionsExt; use test_utilities::*; use super::*; #[test] fn get_directory_stats_detects_nonexistent_directories() { let test_dir = PathBuf::from("/krillinnoooootravez"); if let Ok(output) = get_directory_stats("krillin", &test_dir) { assert!(output.contains("Does not exist.")); } else { panic!("Could not get stats for directory that doesn't exist."); } } #[test] fn get_directory_detects_writability() { let test_dir = setup_test_dir(); if let Ok(output) = get_directory_stats("yajirobe", &test_dir) { assert!(output.contains("Exists")); assert!(output.contains("is readable")); } else { panic!("Could not get stats for directory that doesn't exist."); } cleanup_test_dir(&test_dir); } #[test] fn get_directory_detects_lack_of_writability() { let test_dir = setup_test_dir(); let metadata = metadata(&test_dir).expect("Could not fetch metadata for test dir"); let mut permissions = metadata.permissions(); #[cfg(unix)] { permissions.set_mode(0o311); } set_permissions(&test_dir, permissions.clone()) .expect("Could not set read permissions on dir"); if let Ok(output) = get_directory_stats("roshi", &test_dir) { assert!(output.contains("Exists")); assert!(output.contains("is not readable")); } else { panic!("Could not get stats for directory that doesn't exist."); } #[cfg(unix)] { permissions.set_mode(0o755); } set_permissions(&test_dir, permissions).expect("Could not reset permissions on dir"); cleanup_test_dir(&test_dir); } }