diff --git a/src/cache.rs b/src/cache.rs index ea42af0..d645f76 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -2,6 +2,7 @@ use std::env; use std::fs; use std::io::Read; use std::path::PathBuf; +use std::ffi::OsStr; use reqwest::{Client, Proxy}; use flate2::read::GzDecoder; @@ -32,7 +33,7 @@ impl Cache { } /// Return the path to the cache directory. - fn get_cache_dir(&self) -> Result { + fn get_cache_dir() -> Result { // Allow overriding the cache directory by setting the // $TEALDEER_CACHE_DIR env variable. if let Ok(value) = env::var("TEALDEER_CACHE_DIR") { @@ -78,7 +79,7 @@ impl Cache { } /// Decompress and open the archive - fn decompress(&self, reader: R) -> Archive> { + fn decompress(reader: R) -> Archive> { Archive::new(GzDecoder::new(reader)) } @@ -88,10 +89,10 @@ impl Cache { let bytes: Vec = self.download()?; // Decompress the response body into an `Archive` - let mut archive = self.decompress(&bytes[..]); + let mut archive = Self::decompress(&bytes[..]); // Determine paths - let cache_dir = self.get_cache_dir()?; + let cache_dir = Self::get_cache_dir()?; // Make sure that cache directory exists debug!("Ensure cache directory {:?} exists", &cache_dir); @@ -104,7 +105,7 @@ impl Cache { // But renaming a directory doesn't work across filesystems and Rust // does not yet offer a recursive directory copying function. So for // now, we'll use this approach. - self.clear()?; + Self::clear()?; // Extract archive archive @@ -115,8 +116,8 @@ impl Cache { } /// Return the duration since the cache directory was last modified. - pub fn last_update(&self) -> Option { - if let Ok(cache_dir) = self.get_cache_dir() { + pub fn last_update() -> Option { + if let Ok(cache_dir) = Self::get_cache_dir() { if let Ok(metadata) = fs::metadata(cache_dir.join("tldr-master")) { if let Ok(mtime) = metadata.modified() { let now = SystemTime::now(); @@ -145,7 +146,7 @@ impl Cache { let page_filename = format!("{}.md", name); // Get platform dir - let platforms_dir = match self.get_cache_dir() { + let platforms_dir = match Self::get_cache_dir() { Ok(cache_dir) => cache_dir.join("tldr-master").join("pages"), _ => return None, }; @@ -176,7 +177,7 @@ impl Cache { /// Return the available pages. pub fn list_pages(&self) -> Result, TealdeerError> { // Determine platforms directory and platform - let cache_dir = self.get_cache_dir()?; + let cache_dir = Self::get_cache_dir()?; let platforms_dir = cache_dir.join("tldr-master").join("pages"); let platform_dir = self.get_platform_dir(); @@ -206,10 +207,10 @@ impl Cache { .min_depth(1) // Skip root directory .into_iter() .filter_entry(|e| should_walk(e)) // Filter out pages for other architectures - .filter_map(|e| e.ok()) // Convert results to options, filter out errors + .filter_map(Result::ok) // Convert results to options, filter out errors .filter_map(|e| { let path = e.path(); - let extension = &path.extension().and_then(|s| s.to_str()).unwrap_or(""); + let extension = &path.extension().and_then(OsStr::to_str).unwrap_or(""); if e.file_type().is_file() && extension == &"md" { path.file_stem() .and_then(|stem| stem.to_str().map(|s| s.into())) @@ -224,8 +225,8 @@ impl Cache { } /// Delete the cache directory. - pub fn clear(&self) -> Result<(), TealdeerError> { - let path = self.get_cache_dir()?; + pub fn clear() -> Result<(), TealdeerError> { + let path = Self::get_cache_dir()?; if path.exists() && path.is_dir() { fs::remove_dir_all(&path).map_err(|_| CacheError(format!( "Could not remove cache directory ({}).", diff --git a/src/main.rs b/src/main.rs index d2c00f0..89c7e59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ #![deny(clippy::all)] #![warn(clippy::pedantic)] #![allow(clippy::similar_names)] -#![allow(clippy::stutter)] +#![allow(clippy::module_name_repetitions)] #[cfg(feature = "logging")] extern crate env_logger; @@ -173,9 +173,9 @@ fn configure_pager(_args: &Args, _enable_styles: bool) { } /// Check the cache for freshness -fn check_cache(args: &Args, cache: &Cache) { +fn check_cache(args: &Args) { if !args.flag_update { - match cache.last_update() { + match Cache::last_update() { Some(ago) if ago > MAX_CACHE_AGE => { if args.flag_quiet { return; @@ -198,6 +198,74 @@ fn check_cache(args: &Args, cache: &Cache) { }; } +/// Clear the cache +fn clear_cache(quietly: bool) { + Cache::clear().unwrap_or_else(|e| { + match e { + CacheError(msg) | ConfigError(msg) | UpdateError(msg) => { + eprintln!("Could not delete cache: {}", msg) + } + }; + process::exit(1); + }); + if !quietly { + println!("Successfully deleted cache."); + } +} + +/// Update the cache +fn update_cache(cache: &Cache, quietly: bool) { + cache.update().unwrap_or_else(|e| { + match e { + CacheError(msg) | ConfigError(msg) | UpdateError(msg) => { + eprintln!("Could not update cache: {}", msg) + } + }; + process::exit(1); + }); + if !quietly { + println!("Successfully updated cache."); + } +} + +/// Show the config path +fn show_config_path() { + match get_config_path() { + Ok(config_file_path) => { + println!("Config path is: {}", config_file_path.to_str().unwrap()); + } + Err(ConfigError(msg)) => { + eprintln!("Could not look up config_path: {}", msg); + process::exit(1); + } + Err(_) => { + eprintln!("Unknown error"); + process::exit(1); + } + } +} + +/// Create seed config file and exit +fn create_config_and_exit() { + match make_default_config() { + Ok(config_file_path) => { + println!( + "Successfully created seed config file here: {}", + config_file_path.to_str().unwrap() + ); + process::exit(0); + } + Err(ConfigError(msg)) => { + eprintln!("Could not create seed config: {}", msg); + process::exit(1); + } + Err(_) => { + eprintln!("Unknown error"); + process::exit(1); + } + } +} + #[cfg(feature = "logging")] fn init_log() { env_logger::init(); @@ -272,73 +340,24 @@ fn main() { // Clear cache, pass through if args.flag_clear_cache { - cache.clear().unwrap_or_else(|e| { - match e { - CacheError(msg) | ConfigError(msg) | UpdateError(msg) => { - eprintln!("Could not delete cache: {}", msg) - } - }; - process::exit(1); - }); - if !args.flag_quiet { - println!("Successfully deleted cache."); - } + clear_cache(args.flag_quiet); } // Update cache, pass through if args.flag_update { - cache.update().unwrap_or_else(|e| { - match e { - CacheError(msg) | ConfigError(msg) | UpdateError(msg) => { - eprintln!("Could not update cache: {}", msg) - } - }; - process::exit(1); - }); - if !args.flag_quiet { - println!("Successfully updated cache."); - } + update_cache(&cache, args.flag_quiet); } // Show config file and path, pass through if args.flag_config_path { - match get_config_path() { - Ok(config_file_path) => { - println!("Config path is: {}", config_file_path.to_str().unwrap()); - } - Err(ConfigError(msg)) => { - eprintln!("Could not look up config_path: {}", msg); - process::exit(1); - } - Err(_) => { - eprintln!("Unknown error"); - process::exit(1); - } - } + show_config_path(); } // Create a basic config and exit if args.flag_seed_config { - match make_default_config() { - Ok(config_file_path) => { - println!( - "Successfully created seed config file here: {}", - config_file_path.to_str().unwrap() - ); - process::exit(0); - } - Err(ConfigError(msg)) => { - eprintln!("Could not create seed config: {}", msg); - process::exit(1); - } - Err(_) => { - eprintln!("Unknown error"); - process::exit(1); - } - } + create_config_and_exit(); } - // Render local file and exit if let Some(ref file) = args.flag_render { let path = PathBuf::from(file); @@ -353,7 +372,7 @@ fn main() { // List cached commands and exit if args.flag_list { // Check cache for freshness - check_cache(&args, &cache); + check_cache(&args); // Get list of pages let pages = cache.list_pages().unwrap_or_else(|e| { @@ -374,7 +393,7 @@ fn main() { if let Some(ref command) = args.arg_command { let command = command.join("-"); // Check cache for freshness - check_cache(&args, &cache); + check_cache(&args); // Search for command in cache if let Some(path) = cache.find_page(&command) { diff --git a/src/types.rs b/src/types.rs index 5741a18..f6caa23 100644 --- a/src/types.rs +++ b/src/types.rs @@ -38,7 +38,7 @@ pub enum LineType { } impl<'a> From<&'a str> for LineType { - /// Convert a string slice to a LineType. Newlines and trailing whitespace are trimmed. + /// Convert a string slice to a `LineType`. Newlines and trailing whitespace are trimmed. fn from(line: &'a str) -> Self { let trimmed: &str = line.trim_end(); let mut chars = trimmed.chars(); @@ -56,7 +56,7 @@ impl<'a> From<&'a str> for LineType { ), Some(' ') => LineType::ExampleCode( trimmed - .trim_start_matches(|chr: char| chr.is_whitespace()) + .trim_start_matches(char::is_whitespace) .into(), ), _ => LineType::ExampleText(trimmed.into()),