Skip to content

Commit

Permalink
Merge pull request #35 from johannhof/master
Browse files Browse the repository at this point in the history
Create documents in parallel
  • Loading branch information
Johann Hofmann committed Nov 7, 2015
2 parents 4b593db + 1522230 commit 4b3f1f7
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ getopts = "0.2.14"
markdown = "0.1"
liquid = "0.1"
walkdir = "0.1"
crossbeam = "0.1.5"

[dev-dependencies]
difference = "0.4"
31 changes: 25 additions & 6 deletions src/cobalt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::io;
use crossbeam;

use std::sync::Arc;
use std::fs::{self, File};
use std::io::Read;
use std::io::{self, Read};
use std::path::Path;
use std::collections::HashMap;
use std::ffi::OsStr;
Expand Down Expand Up @@ -29,7 +31,7 @@ pub fn build(source: &Path, dest: &Path, layout_str: &str, posts_str: &str) -> i
.expect(&format!("No file name from {:?}", entry))
.to_str()
.expect(&format!("Invalid UTF-8 in {:?}", entry))
.to_string(),
.to_owned(),
text);
}

Expand All @@ -51,8 +53,25 @@ pub fn build(source: &Path, dest: &Path, layout_str: &str, posts_str: &str) -> i
}
}

for doc in documents.iter() {
try!(doc.create_file(dest, &layouts, &post_data));
let mut handles = vec![];

// generate documents (in parallel)
// TODO I'm probably underutilizing crossbeam
crossbeam::scope(|scope| {
let post_data = Arc::new(post_data);
let layouts = Arc::new(layouts);
for doc in &documents {
let post_data = post_data.clone();
let layouts = layouts.clone();
let handle = scope.spawn(move || {
doc.create_file(dest, &layouts, &post_data)
});
handles.push(handle);
}
});

for handle in handles {
try!(handle.join());
}

// copy all remaining files in the source to the destination
Expand Down Expand Up @@ -105,7 +124,7 @@ fn parse_document(path: &Path, source: &Path) -> Document {
.expect(&format!("Empty path"));
let markdown = path.extension().unwrap_or(OsStr::new("")) == OsStr::new("md");

Document::new(new_path.to_string(), attributes, content, markdown)
Document::new(new_path.to_owned(), attributes, content, markdown)
}

fn parse_file(path: &Path) -> io::Result<String> {
Expand Down
10 changes: 5 additions & 5 deletions src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Document {
let mut data = HashMap::new();
for key in self.attributes.keys() {
if let Some(val) = self.attributes.get(key) {
data.insert(key.to_string(), Value::Str(val.clone()));
data.insert(key.to_owned(), Value::Str(val.clone()));
}
}
data
Expand All @@ -50,7 +50,7 @@ impl Document {
let mut data = Context::with_values(self.get_attributes());
data.set_val("posts", Value::Array(post_data.clone()));

Ok(template.render(&mut data).unwrap_or("".to_string()))
Ok(template.render(&mut data).unwrap_or(String::new()))
}

pub fn create_file(&self,
Expand All @@ -66,7 +66,7 @@ impl Document {

let file_path = file_path_buf.as_path();

let layout_path = self.attributes.get(&"@extends".to_string()).expect(&format!("No @extends line creating {:?}", self.name));
let layout_path = self.attributes.get(&"@extends".to_owned()).expect(&format!("No @extends line creating {:?}", self.name));
let layout = layouts.get(layout_path).expect(&format!("No layout path {:?} creating {:?}", layout_path, self.name));

// create target directories if any exist
Expand All @@ -84,7 +84,7 @@ impl Document {
Ok(x) => x,
Err(e) => {
println!("Warning, liquid failed: {}", e);
"".to_string()
String::new()
}
};
if self.markdown {
Expand All @@ -108,7 +108,7 @@ impl Document {
}
};

let res = template.render(&mut data).unwrap_or("".to_string());
let res = template.render(&mut data).unwrap_or(String::new());

println!("Created {}", file_path.display());
file.write_all(&res.into_bytes())
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![deny(warnings)]

extern crate liquid;
extern crate markdown;
extern crate walkdir;
extern crate crossbeam;

// without this main.rs would have to use cobalt::cobalt
// with this approach you can explicitly say which part of a module is public and which not
Expand Down

0 comments on commit 4b3f1f7

Please sign in to comment.