diff --git a/src/cache.rs b/src/cache.rs index cb57a4b..05efff2 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -87,4 +87,44 @@ impl Cache { None } + pub fn find_page(&self, name: &str) -> Option { + // Build page file name + let page_filename = format!("{}.md", name); + + // Get platform dir + let cache_dir = match self.get_cache_dir() { + Ok(dir) => dir, + Err(_) => return None, + }; + let platforms_dir = cache_dir.join("tldr-master").join("pages"); + + // Determine platform + let platform = if cfg!(target_os = "linux") { + Some("linux") + } else if cfg!(target_os = "macos") { + Some("osx") + } else { + None // TODO: Does rust support Sun OS? + }; + + // Search for the page in the platform specific directory + if let Some(pf) = platform { + let path = platforms_dir.join(&pf).join(&page_filename); + if path.exists() && path.is_file() { + return Some(path); + } + } + + // If platform is not supported or if platform specific page does not exist, + // look up the page in the "common" directory. + let path = platforms_dir.join("common").join(&page_filename); + + // Return it if it exists, otherwise give up and return `None` + if path.exists() && path.is_file() { + Some(path) + } else { + None + } + } + } diff --git a/src/main.rs b/src/main.rs index 5f6becb..9473064 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ extern crate time; use std::io::BufReader; use std::fs::File; +use std::path::{Path, PathBuf}; use std::process; use docopt::Docopt; @@ -77,13 +78,19 @@ struct Args { } -/// Open file, return a `BufRead` instance -fn get_file_reader(filepath: &str) -> Result, String> { +/// Print page by path +fn print_page(path: &Path) -> Result<(), String> { + // Open file let file = try!( - File::open(filepath) - .map_err(|msg| format!("Could not open file: {}", msg)) + File::open(path).map_err(|msg| format!("Could not open file: {}", msg)) ); - Ok(BufReader::new(file)) + let reader = BufReader::new(file); + + // Create tokenizer and print output + let mut tokenizer = Tokenizer::new(reader); + print_lines(&mut tokenizer); + + Ok(()) } @@ -134,17 +141,13 @@ fn main() { // Render local file and exit if let Some(file) = args.flag_render { - // Open file - let reader = get_file_reader(&file).unwrap_or_else(|msg| { + let path = PathBuf::from(file); + if let Err(msg) = print_page(&path) { println!("{}", msg); process::exit(1); - }); - - // Create tokenizer and print output - let mut tokenizer = Tokenizer::new(reader); - print_lines(&mut tokenizer); - - process::exit(0); + } else { + process::exit(0); + }; } // List cached commands and exit @@ -166,7 +169,7 @@ fn main() { match cache.last_update() { Some(ago) if ago > MAX_CACHE_AGE => { println!("Cache wasn't updated in {} days.", MAX_CACHE_AGE / 24 / 3600); - println!("You should probably run `tldr --update` soon."); + println!("You should probably run `tldr --update` soon."); }, None => { println!("Cache not found. Please run `tldr --update`."); @@ -177,8 +180,19 @@ fn main() { } // Search for command in cache - println!("Page rendering from cache not yet implemented."); - process::exit(1); + if let Some(path) = cache.find_page(&command) { + if let Err(msg) = print_page(&path) { + println!("{}", msg); + process::exit(1); + } else { + process::exit(0); + } + } else { + println!("Page {} not found in cache", &command); + println!("Try updating with `tldr --update`, or submit a pull request to:"); + println!("https://github.com/tldr-pages/tldr"); + process::exit(1); + } } // Some flags can be run without a command.