diff --git a/Cargo.lock b/Cargo.lock index 9d42702..eb9a42a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,7 @@ name = "gutenberg" version = "0.1.0" dependencies = [ + "chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index d68253f..8ebd713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ serde_derive = "0.9" tera = "0.8" slug = "0.1" syntect = "1" +chrono = "0.3" # Below is for the serve cmd staticfile = "0.4" diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index cb3aeb5..6bca8e3 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -5,7 +5,6 @@ use std::time::Duration; use std::thread; use iron::{Iron, Request, IronResult, Response, status}; -use iron::modifiers::Header; use mount::Mount; use staticfile::Static; use notify::{Watcher, RecursiveMode, watcher}; @@ -17,7 +16,7 @@ use errors::{Result}; const LIVE_RELOAD: &'static [u8; 37809] = include_bytes!("livereload.js"); -fn livereload_handler(req: &mut Request) -> IronResult { +fn livereload_handler(_: &mut Request) -> IronResult { Ok(Response::with((status::Ok, String::from_utf8(LIVE_RELOAD.to_vec()).unwrap()))) } diff --git a/src/front_matter.rs b/src/front_matter.rs index e83f4c7..1bf9411 100644 --- a/src/front_matter.rs +++ b/src/front_matter.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use toml; use tera::Value; +use chrono::prelude::*; use errors::{Result}; @@ -67,6 +68,19 @@ impl FrontMatter { Ok(f) } + + pub fn parse_date(&self) -> Option { + match self.date { + Some(ref d) => { + if d.contains("T") { + DateTime::parse_from_rfc3339(d).ok().and_then(|s| Some(s.naive_local())) + } else { + NaiveDate::parse_from_str(d, "%Y-%m-%d").ok().and_then(|s| Some(s.and_hms(0,0,0))) + } + }, + None => None, + } + } } @@ -183,6 +197,7 @@ slug = """#; let res = FrontMatter::parse(content); assert!(res.is_err()); } + #[test] fn test_errors_on_present_but_empty_url() { let content = r#" @@ -192,4 +207,34 @@ url = """#; let res = FrontMatter::parse(content); assert!(res.is_err()); } + + #[test] + fn test_parse_date_yyyy_mm_dd() { + let content = r#" +title = "Hello" +description = "hey there" +date = "2016-10-10""#; + let res = FrontMatter::parse(content).unwrap(); + assert!(res.parse_date().is_some()); + } + + #[test] + fn test_parse_date_rfc3339() { + let content = r#" +title = "Hello" +description = "hey there" +date = "2002-10-02T15:00:00Z""#; + let res = FrontMatter::parse(content).unwrap(); + assert!(res.parse_date().is_some()); + } + + #[test] + fn test_cant_parse_random_date_format() { + let content = r#" +title = "Hello" +description = "hey there" +date = "2002/10/12""#; + let res = FrontMatter::parse(content).unwrap(); + assert!(res.parse_date().is_none()); + } } diff --git a/src/main.rs b/src/main.rs index 80c4ce3..37e8f0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ extern crate tera; extern crate glob; extern crate syntect; extern crate slug; +extern crate chrono; extern crate staticfile; extern crate iron; diff --git a/src/page.rs b/src/page.rs index b763ec0..2d2beb2 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,4 +1,5 @@ /// A page, can be a blog post or a basic page +use std::cmp::Ordering; use std::fs::File; use std::io::prelude::*; use std::path::Path; @@ -176,10 +177,30 @@ impl ser::Serialize for Page { } } -// Order pages by date, no-op for now -// TODO: impl PartialOrd on Vec so we can use sort()? -pub fn order_pages(pages: Vec) -> Vec { - pages +impl PartialOrd for Page { + fn partial_cmp(&self, other: &Page) -> Option { + if self.meta.date.is_none() { + println!("No self data"); + return Some(Ordering::Less); + } + + if other.meta.date.is_none() { + println!("No other date"); + return Some(Ordering::Greater); + } + + let this_date = self.meta.parse_date().unwrap(); + let other_date = other.meta.parse_date().unwrap(); + + if this_date > other_date { + return Some(Ordering::Less); + } + if this_date < other_date { + return Some(Ordering::Greater); + } + + Some(Ordering::Equal) + } } diff --git a/src/site.rs b/src/site.rs index 79e023b..f133e63 100644 --- a/src/site.rs +++ b/src/site.rs @@ -118,6 +118,7 @@ impl Site { // And finally the index page let mut context = Context::new(); + pages.sort_by(|a, b| a.partial_cmp(b).unwrap()); context.add("pages", &pages); context.add("config", &self.config); let index = self.templates.render("index.html", &context)?;