diff --git a/src/book/mdbook.rs b/src/book/mdbook.rs index 02430414..2209bc36 100644 --- a/src/book/mdbook.rs +++ b/src/book/mdbook.rs @@ -9,7 +9,7 @@ use std::process::Command; use {BookConfig, BookItem, theme, parse, utils}; use book::BookItems; use renderer::{Renderer, HtmlHandlebars}; -use utils::{PathExt, create_path}; + pub struct MDBook { config: BookConfig, @@ -96,7 +96,7 @@ impl MDBook { debug!("[fn]: init"); if !self.config.get_root().exists() { - create_path(self.config.get_root()).unwrap(); + fs::create_dir_all(self.config.get_root()).unwrap(); output!("{:?} created", self.config.get_root()); } diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index e877c43e..68753ceb 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -8,7 +8,7 @@ use book::bookitem::BookItem; use {utils, theme}; use std::path::{Path, PathBuf}; -use std::fs::File; +use std::fs::{self, File}; use std::error::Error; use std::io::{self, Read, Write}; use std::collections::BTreeMap; @@ -50,7 +50,7 @@ impl Renderer for HtmlHandlebars { // Check if dest directory exists debug!("[*]: Check if destination directory exists"); - if let Err(_) = utils::create_path(book.get_dest()) { + if let Err(_) = fs::create_dir_all(book.get_dest()) { return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexpected error when constructing destination path"))) } @@ -159,41 +159,68 @@ impl Renderer for HtmlHandlebars { debug!("[*] Copy static files"); // JavaScript - let mut js_file = try!(File::create(book.get_dest().join("book.js"))); + let mut js_file = if let Ok(f) = File::create(book.get_dest().join("book.js")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create book.js"))) + }; try!(js_file.write_all(&theme.js)); // Css - let mut css_file = try!(File::create(book.get_dest().join("book.css"))); + let mut css_file = if let Ok(f) = File::create(book.get_dest().join("book.css")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create book.css"))) + }; try!(css_file.write_all(&theme.css)); // JQuery local fallback - let mut jquery = try!(File::create(book.get_dest().join("jquery.js"))); + let mut jquery = if let Ok(f) = File::create(book.get_dest().join("jquery.js")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create jquery.js"))) + }; try!(jquery.write_all(&theme.jquery)); - // Font Awesome local fallback - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/css/font-awesome").with_extension("css"))); - try!(font_awesome.write_all(theme::FONT_AWESOME)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.eot"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_EOT)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.svg"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_SVG)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.ttf"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_TTF)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff2"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2)); - let mut font_awesome = try!(utils::create_file(&book.get_dest().join("_FontAwesome/fonts/FontAwesome.ttf"))); - try!(font_awesome.write_all(theme::FONT_AWESOME_TTF)); - // syntax highlighting - let mut highlight_css = try!(File::create(book.get_dest().join("highlight.css"))); + let mut highlight_css = if let Ok(f) = File::create(book.get_dest().join("highlight.css")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create highlight.css"))) + }; try!(highlight_css.write_all(&theme.highlight_css)); - let mut tomorrow_night_css = try!(File::create(book.get_dest().join("tomorrow-night.css"))); + + let mut tomorrow_night_css = if let Ok(f) = File::create(book.get_dest().join("tomorrow-night.css")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create tomorrow-night.css"))) + }; try!(tomorrow_night_css.write_all(&theme.tomorrow_night_css)); - let mut highlight_js = try!(File::create(book.get_dest().join("highlight.js"))); + + let mut highlight_js = if let Ok(f) = File::create(book.get_dest().join("highlight.js")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create highlight.js"))) + }; try!(highlight_js.write_all(&theme.highlight_js)); + // Font Awesome local fallback + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/css/font-awesome.css")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create font-awesome.css"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.eot")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.eot"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_EOT)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.svg")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.svg"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_SVG)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.ttf")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.ttf"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_TTF)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/fontawesome-webfont.woff2")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create fontawesome-webfont.woff2"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_WOFF2)); + let mut font_awesome = if let Ok(f) = utils::create_file(&book.get_dest().join("_FontAwesome/fonts/FontAwesome.ttf")) { f } else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Could not create FontAwesome.ttf"))) + }; + try!(font_awesome.write_all(theme::FONT_AWESOME_TTF)); // Copy all remaining files try!(utils::copy_files_except_ext(book.get_src(), book.get_dest(), true, &["md"])); diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 703a994c..5fca68fd 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -2,7 +2,6 @@ use std::path::Path; use std::fs::File; use std::io::Read; -use utils::{PathExt}; pub static INDEX: &'static [u8] = include_bytes!("index.hbs"); pub static CSS: &'static [u8] = include_bytes!("book.css"); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ef6f066e..f6ab3af5 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,33 +1,12 @@ extern crate pulldown_cmark; -use std::path::{Path, PathBuf, Component}; +use std::path::{Path, Component}; use std::error::Error; +use std::io; use std::fs::{self, metadata, File}; use self::pulldown_cmark::{Parser, html, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES}; -/// This is copied from the rust source code until Path_ Ext stabilizes. -/// You can use it, but be aware that it will be removed when those features go to rust stable -pub trait PathExt { - fn exists(&self) -> bool; - fn is_file(&self) -> bool; - fn is_dir(&self) -> bool; -} - -impl PathExt for Path { - fn exists(&self) -> bool { - metadata(self).is_ok() - } - - fn is_file(&self) -> bool { - metadata(self).map(|s| s.is_file()).unwrap_or(false) - } - - fn is_dir(&self) -> bool { - metadata(self).map(|s| s.is_dir()).unwrap_or(false) - } -} - /// Takes a path and returns a path containing just enough `../` to point to the root of the given path. /// /// This is mostly interesting for a relative path to point back to the directory from where the @@ -65,46 +44,7 @@ pub fn path_to_root(path: &Path) -> String { }) } -/// This function checks for every component in a path if the directory exists, -/// if it does not it is created. -pub fn create_path(path: &Path) -> Result<(), Box> { - debug!("[fn]: create_path"); - - // Create directories if they do not exist - let mut constructed_path = PathBuf::new(); - - for component in path.components() { - - let dir; - match component { - Component::Normal(_) => { dir = PathBuf::from(component.as_os_str()); }, - Component::RootDir => { - debug!("[*]: Root directory"); - // This doesn't look very compatible with Windows... - constructed_path.push("/"); - continue - }, - _ => continue, - } - - constructed_path.push(&dir); - debug!("[*]: {:?}", constructed_path); - - if !constructed_path.exists() || !constructed_path.is_dir() { - try!(fs::create_dir(&constructed_path)); - debug!("[*]: Directory created {:?}", constructed_path); - } else { - debug!("[*]: Directory exists {:?}", constructed_path); - continue - } - - } - - debug!("[*]: Constructed path: {:?}", constructed_path); - - Ok(()) -} /// This function creates a file and returns it. But before creating the file it checks every /// directory in the path to see if it exists, and if it does not it will be created. @@ -114,11 +54,19 @@ pub fn create_file(path: &Path) -> Result> { // Construct path if let Some(p) = path.parent() { - try!(create_path(p)); + debug!("Parent directory is: {:?}", p); + + try!(fs::create_dir_all(p)); } debug!("[*]: Create file: {:?}", path); - let f = try!(File::create(path)); + let f = match File::create(path) { + Ok(f) => f, + Err(e) => { + debug!("File::create: {}", e); + return Err(Box::new(io::Error::new(io::ErrorKind::Other, format!("{}", e)))) + }, + }; Ok(f) } @@ -172,7 +120,7 @@ pub fn copy_files_except_ext(from: &Path, to: &Path, recursive: bool, ext_blackl if let Some(ext) = entry.path().extension() { if ext_blacklist.contains(&ext.to_str().unwrap()) { continue } debug!("[*] creating path for file: {:?}", &to.join(entry.path().file_name().expect("a file should have a file name..."))); - //try!(create_path(&to.join(entry.path()))); + output!("[*] copying file: {:?}\n to {:?}", entry.path(), &to.join(entry.path().file_name().expect("a file should have a file name..."))); try!(fs::copy(entry.path(), &to.join(entry.path().file_name().expect("a file should have a file name...")))); }