diff --git a/src/book/bookitem.rs b/src/book/bookitem.rs index e3e40225..d8f43fae 100644 --- a/src/book/bookitem.rs +++ b/src/book/bookitem.rs @@ -2,6 +2,8 @@ use serde::{Serialize, Serializer}; use serde::ser::SerializeStruct; use std::path::PathBuf; +use errors::*; + #[derive(Debug, Clone)] pub enum BookItem { Chapter(String, Chapter), // String = section @@ -37,7 +39,7 @@ impl Chapter { impl Serialize for Chapter { - fn serialize(&self, serializer: S) -> Result + fn serialize(&self, serializer: S) -> ::std::result::Result where S: Serializer { let mut struct_ = serializer.serialize_struct("Chapter", 2)?; diff --git a/src/book/mod.rs b/src/book/mod.rs index 35ed41f7..fa902648 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -4,14 +4,12 @@ pub use self::bookitem::{BookItem, BookItems}; use std::path::{Path, PathBuf}; use std::fs::{self, File}; -use std::error::Error; -use std::io; -use std::io::{Read, Write}; -use std::io::ErrorKind; +use std::io::{self, Read, Write}; use std::process::Command; use {theme, parse, utils}; use renderer::{Renderer, HtmlHandlebars}; +use errors::*; use config::BookConfig; use config::tomlconfig::TomlConfig; @@ -129,7 +127,7 @@ impl MDBook { /// and adds a `SUMMARY.md` and a /// `chapter_1.md` to the source directory. - pub fn init(&mut self) -> Result<(), Box> { + pub fn init(&mut self) -> Result<()> { debug!("[fn]: init"); @@ -239,7 +237,7 @@ impl MDBook { /// method of the current renderer. /// /// It is the renderer who generates all the output files. - pub fn build(&mut self) -> Result<(), Box> { + pub fn build(&mut self) -> Result<()> { debug!("[fn]: build"); self.init()?; @@ -249,9 +247,7 @@ impl MDBook { utils::fs::remove_dir_content(htmlconfig.get_destination())?; } - self.renderer.render(&self)?; - - Ok(()) + self.renderer.render(&self) } @@ -259,7 +255,7 @@ impl MDBook { self.config.get_root().join(".gitignore") } - pub fn copy_theme(&self) -> Result<(), Box> { + pub fn copy_theme(&self) -> Result<()> { debug!("[fn]: copy_theme"); if let Some(htmlconfig) = self.config.get_html_config() { @@ -298,16 +294,14 @@ impl MDBook { Ok(()) } - pub fn write_file>(&self, filename: P, content: &[u8]) -> Result<(), Box> { + pub fn write_file>(&self, filename: P, content: &[u8]) -> Result<()> { let path = self.get_destination() .ok_or(String::from("HtmlConfig not set, could not find a destination"))? .join(filename); - utils::fs::create_file(&path) - .and_then(|mut file| file.write_all(content)) - .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Could not create {}: {}", path.display(), e)))?; - - Ok(()) + utils::fs::create_file(&path)? + .write_all(content) + .map_err(|e| e.into()) } /// Parses the `book.json` file (if it exists) to extract @@ -315,7 +309,7 @@ impl MDBook { /// The `book.json` file should be in the root directory of the book. /// The root directory is the one specified when creating a new `MDBook` - pub fn read_config(mut self) -> Result> { + pub fn read_config(mut self) -> Result { let toml = self.get_root().join("book.toml"); let json = self.get_root().join("book.json"); @@ -369,9 +363,9 @@ impl MDBook { self } - pub fn test(&mut self) -> Result<(), Box> { + pub fn test(&mut self) -> Result<()> { // read in the chapters - self.parse_summary()?; + self.parse_summary().chain_err(|| "Couldn't parse summary")?; for item in self.iter() { if let BookItem::Chapter(_, ref ch) = *item { @@ -381,15 +375,10 @@ impl MDBook { println!("[*]: Testing file: {:?}", path); - let output_result = Command::new("rustdoc").arg(&path).arg("--test").output(); - let output = output_result?; + let output = Command::new("rustdoc").arg(&path).arg("--test").output()?; if !output.status.success() { - return Err(Box::new(io::Error::new(ErrorKind::Other, - format!("{}\n{}", - String::from_utf8_lossy(&output.stdout), - String::from_utf8_lossy(&output.stderr)))) as - Box); + bail!(ErrorKind::Subprocess("Rustdoc returned an error".to_string(), output)); } } } @@ -539,7 +528,7 @@ impl MDBook { } // Construct book - fn parse_summary(&mut self) -> Result<(), Box> { + fn parse_summary(&mut self) -> Result<()> { // When append becomes stable, use self.content.append() ... self.content = parse::construct_bookitems(&self.get_source().join("SUMMARY.md"))?; Ok(()) diff --git a/src/lib.rs b/src/lib.rs index 1476f7db..0f1f2121 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,5 +100,11 @@ pub mod errors { foreign_links { Io(::std::io::Error); } + + errors { + Subprocess(message: String, output: ::std::process::Output) { + description("A subprocess failed") + } + } } } \ No newline at end of file diff --git a/src/utils/fs.rs b/src/utils/fs.rs index 43e934c0..0bb99976 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -1,16 +1,16 @@ use std::path::{Path, PathBuf, Component}; -use std::error::Error; +use errors::*; use std::io::{self, Read}; use std::fs::{self, File}; /// Takes a path to a file and try to read the file into a String -pub fn file_to_string(path: &Path) -> Result> { +pub fn file_to_string(path: &Path) -> Result { let mut file = match File::open(path) { Ok(f) => f, Err(e) => { debug!("[*]: Failed to open {:?}", path); - return Err(Box::new(e)); + bail!(e); }, }; @@ -18,7 +18,7 @@ pub fn file_to_string(path: &Path) -> Result> { if let Err(e) = file.read_to_string(&mut content) { debug!("[*]: Failed to read {:?}", path); - return Err(Box::new(e)); + bail!(e); } Ok(content) @@ -72,7 +72,7 @@ pub fn path_to_root>(path: P) -> String { /// 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) -> io::Result { +pub fn create_file(path: &Path) -> Result { debug!("[fn]: create_file"); // Construct path @@ -83,12 +83,12 @@ pub fn create_file(path: &Path) -> io::Result { } debug!("[*]: Create file: {:?}", path); - File::create(path) + File::create(path).map_err(|e| e.into()) } /// Removes all the content of a directory but not the directory itself -pub fn remove_dir_content(dir: &Path) -> Result<(), Box> { +pub fn remove_dir_content(dir: &Path) -> Result<()> { for item in fs::read_dir(dir)? { if let Ok(item) = item { let item = item.path(); @@ -108,7 +108,7 @@ pub fn remove_dir_content(dir: &Path) -> Result<(), Box> { /// with the extensions given in the `ext_blacklist` array pub fn copy_files_except_ext(from: &Path, to: &Path, recursive: bool, ext_blacklist: &[&str]) - -> Result<(), Box> { + -> Result<()> { debug!("[fn] copy_files_except_ext"); // Check that from and to are different if from == to {