diff --git a/src/lib.rs b/src/lib.rs index 504b0af2..edc2fe9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ //! I have regrouped some useful functions in the [utils](utils/index.html) module, like the following function //! //! ```ignore -//! utils::path::create_path(path: &Path) +//! utils::create_path(path: &Path) //! ``` //! This function creates all the directories in a given path if they do not exist //! diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 3079e168..106b6066 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -47,7 +47,7 @@ impl Renderer for HtmlHandlebars { // Check if dest directory exists debug!("[*]: Check if destination directory exists"); - match utils::path::create_path(config.dest()) { + match utils::create_path(config.dest()) { Err(_) => return Err(Box::new(io::Error::new(io::ErrorKind::Other, "Unexcpected error when constructing destination path"))), _ => {}, }; @@ -80,7 +80,7 @@ impl Renderer for HtmlHandlebars { // Remove path to root from previous file and render content for this one data.remove("path_to_root"); - data.insert("path_to_root".to_string(), utils::path::path_to_root(&item.path).to_json()); + data.insert("path_to_root".to_string(), utils::path_to_root(&item.path).to_json()); // Rendere the handlebars template with the data debug!("[*]: Render template"); @@ -88,7 +88,7 @@ impl Renderer for HtmlHandlebars { debug!("[*]: Create file {:?}", &config.dest().join(&item.path).with_extension("html")); // Write to file - let mut file = try!(utils::path::create_file(&config.dest().join(&item.path).with_extension("html"))); + let mut file = try!(utils::create_file(&config.dest().join(&item.path).with_extension("html"))); output!("[*] Creating {:?} ✓", &config.dest().join(&item.path).with_extension("html")); try!(file.write_all(&rendered.into_bytes())); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 4da97892..5a7c1fd0 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,108 @@ -pub mod path; +use std::path::{Path, PathBuf, Component}; +use std::error::Error; +use std::fs::{self, metadata, File}; + + +/// 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 +/// path starts. +/// +/// ```ignore +/// let mut path = Path::new("some/relative/path"); +/// +/// println!("{}", path_to_root(&path)); +/// ``` +/// +/// **Outputs** +/// +/// ```text +/// "../../" +/// ``` +/// +/// **note:** it's not very fool-proof, if you find a situation where it doesn't return the correct +/// path. Consider [submitting a new issue](https://github.com/azerupi/mdBook/issues) or a +/// [pull-request](https://github.com/azerupi/mdBook/pulls) to improve it. + +pub fn path_to_root(path: &Path) -> String { + debug!("[fn]: path_to_root"); + // Remove filename and add "../" for every directory + + path.to_path_buf().parent().expect("") + .components().fold(String::new(), |mut s, c| { + match c { + Component::Normal(_) => s.push_str("../"), + _ => { + debug!("[*]: Other path component... {:?}", c); + } + } + s + }) +} + +/// 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 mut 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); + + // Check if path exists + match metadata(&constructed_path) { + // Any way to combine the Err and first Ok branch ?? + Err(_) => { + try!(fs::create_dir(&constructed_path)); + debug!("[*]: Directory created {:?}", constructed_path); + }, + Ok(f) => { + if !f.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. + +pub fn create_file(path: &Path) -> Result> { + debug!("[fn]: create_file"); + + // Construct path + if let Some(p) = path.parent() { + try!(create_path(p)); + } + + debug!("[*]: Create file: {}", path); + let f = try!(File::create(path)); + + Ok(f) +} diff --git a/src/utils/path.rs b/src/utils/path.rs deleted file mode 100644 index 4c815929..00000000 --- a/src/utils/path.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::path::{Path, PathBuf, Component}; -use std::error::Error; -use std::fs::{self, metadata, File}; - -pub fn path_to_root(path: &Path) -> String { - debug!("[fn]: path_to_root"); - // Remove filename and add "../" for every directory - - path.to_path_buf().parent().expect("") - .components().fold(String::new(), |mut s, c| { - match c { - Component::Normal(_) => s.push_str("../"), - _ => { - debug!("[*]: Other path component... {:?}", c); - } - } - s - }) -} - -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 mut 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); - - // Check if path exists - match metadata(&constructed_path) { - // Any way to combine the Err and first Ok branch ?? - Err(_) => { - try!(fs::create_dir(&constructed_path)); - debug!("[*]: Directory created {:?}", constructed_path); - }, - Ok(f) => { - if !f.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(()) -} - -pub fn create_file(path: &Path) -> Result> { - debug!("[fn]: create_file"); - - // Construct path - if let Some(p) = path.parent() { - try!(create_path(p)); - } - - debug!("[*]: Create file: {}", path); - let f = try!(File::create(path)); - - Ok(f) -}