Parse date only once for pages
This commit is contained in:
parent
69dce561c8
commit
9461769bcc
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -250,6 +250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ tera = "0.11"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
slug = "0.1"
|
slug = "0.1"
|
||||||
rayon = "1"
|
rayon = "1"
|
||||||
chrono = "0.4"
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
||||||
errors = { path = "../errors" }
|
errors = { path = "../errors" }
|
||||||
config = { path = "../config" }
|
config = { path = "../config" }
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
|
|
||||||
use chrono::Datelike;
|
|
||||||
use tera::{Tera, Context as TeraContext};
|
use tera::{Tera, Context as TeraContext};
|
||||||
use serde::ser::{SerializeStruct, self};
|
use serde::ser::{SerializeStruct, self};
|
||||||
use slug::slugify;
|
use slug::slugify;
|
||||||
|
@ -263,11 +262,10 @@ impl ser::Serialize for Page {
|
||||||
state.serialize_field("title", &self.meta.title)?;
|
state.serialize_field("title", &self.meta.title)?;
|
||||||
state.serialize_field("description", &self.meta.description)?;
|
state.serialize_field("description", &self.meta.description)?;
|
||||||
state.serialize_field("date", &self.meta.date)?;
|
state.serialize_field("date", &self.meta.date)?;
|
||||||
if let Some(chrono_datetime) = self.meta.date() {
|
if let Some(d) = self.meta.datetime_tuple {
|
||||||
let d = chrono_datetime.date();
|
state.serialize_field("year", &d.0)?;
|
||||||
state.serialize_field("year", &d.year())?;
|
state.serialize_field("month", &d.1)?;
|
||||||
state.serialize_field("month", &d.month())?;
|
state.serialize_field("day", &d.2)?;
|
||||||
state.serialize_field("day", &d.day())?;
|
|
||||||
} else {
|
} else {
|
||||||
state.serialize_field::<Option<usize>>("year", &None)?;
|
state.serialize_field::<Option<usize>>("year", &None)?;
|
||||||
state.serialize_field::<Option<usize>>("month", &None)?;
|
state.serialize_field::<Option<usize>>("month", &None)?;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use front_matter::SortBy;
|
||||||
/// To remove if `sort_pages` is changed to work on borrowed values
|
/// To remove if `sort_pages` is changed to work on borrowed values
|
||||||
/// This cannot be used in `sort_pages` currently as it takes &&Page instead of &Page
|
/// This cannot be used in `sort_pages` currently as it takes &&Page instead of &Page
|
||||||
pub fn sort_pages_by_date(a: &&Page, b: &&Page) -> Ordering {
|
pub fn sort_pages_by_date(a: &&Page, b: &&Page) -> Ordering {
|
||||||
let ord = b.meta.date().unwrap().cmp(&a.meta.date().unwrap());
|
let ord = b.meta.datetime.unwrap().cmp(&a.meta.datetime.unwrap());
|
||||||
if ord == Ordering::Equal {
|
if ord == Ordering::Equal {
|
||||||
a.permalink.cmp(&b.permalink)
|
a.permalink.cmp(&b.permalink)
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,7 +33,7 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.partition(|page| {
|
.partition(|page| {
|
||||||
match sort_by {
|
match sort_by {
|
||||||
SortBy::Date => page.meta.date.is_some(),
|
SortBy::Date => page.meta.datetime.is_some(),
|
||||||
SortBy::Weight => page.meta.weight.is_some(),
|
SortBy::Weight => page.meta.weight.is_some(),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
|
||||||
match sort_by {
|
match sort_by {
|
||||||
SortBy::Date => {
|
SortBy::Date => {
|
||||||
can_be_sorted.par_sort_unstable_by(|a, b| {
|
can_be_sorted.par_sort_unstable_by(|a, b| {
|
||||||
let ord = b.meta.date().unwrap().cmp(&a.meta.date().unwrap());
|
let ord = b.meta.datetime.unwrap().cmp(&a.meta.datetime.unwrap());
|
||||||
if ord == Ordering::Equal {
|
if ord == Ordering::Equal {
|
||||||
a.permalink.cmp(&b.permalink)
|
a.permalink.cmp(&b.permalink)
|
||||||
} else {
|
} else {
|
||||||
|
@ -159,6 +159,7 @@ mod tests {
|
||||||
fn create_page_with_date(date: &str) -> Page {
|
fn create_page_with_date(date: &str) -> Page {
|
||||||
let mut front_matter = PageFrontMatter::default();
|
let mut front_matter = PageFrontMatter::default();
|
||||||
front_matter.date = Some(date.to_string());
|
front_matter.date = Some(date.to_string());
|
||||||
|
front_matter.date_to_datetime();
|
||||||
Page::new("content/hello.md", front_matter)
|
Page::new("content/hello.md", front_matter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ fn fix_toml_dates(table: Map<String, Value>) -> Value {
|
||||||
|
|
||||||
|
|
||||||
/// The front matter of every page
|
/// The front matter of every page
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct PageFrontMatter {
|
pub struct PageFrontMatter {
|
||||||
/// <title> of the page
|
/// <title> of the page
|
||||||
|
@ -72,6 +72,12 @@ pub struct PageFrontMatter {
|
||||||
/// Date if we want to order pages (ie blog post)
|
/// Date if we want to order pages (ie blog post)
|
||||||
#[serde(default, deserialize_with = "from_toml_datetime")]
|
#[serde(default, deserialize_with = "from_toml_datetime")]
|
||||||
pub date: Option<String>,
|
pub date: Option<String>,
|
||||||
|
/// Chrono converted datetime
|
||||||
|
#[serde(default, skip_deserializing)]
|
||||||
|
pub datetime: Option<NaiveDateTime>,
|
||||||
|
/// The converted date into a (year, month, day) tuple
|
||||||
|
#[serde(default, skip_deserializing)]
|
||||||
|
pub datetime_tuple: Option<(i32, u32, u32)>,
|
||||||
/// Whether this page is a draft and should be ignored for pagination etc
|
/// Whether this page is a draft and should be ignored for pagination etc
|
||||||
pub draft: bool,
|
pub draft: bool,
|
||||||
/// The page slug. Will be used instead of the filename if present
|
/// The page slug. Will be used instead of the filename if present
|
||||||
|
@ -124,12 +130,16 @@ impl PageFrontMatter {
|
||||||
Value::Object(o) => o,
|
Value::Object(o) => o,
|
||||||
_ => unreachable!("Got something other than a table in page extra"),
|
_ => unreachable!("Got something other than a table in page extra"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
f.date_to_datetime();
|
||||||
|
|
||||||
Ok(f)
|
Ok(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the TOML datetime to a Chrono naive datetime
|
/// Converts the TOML datetime to a Chrono naive datetime
|
||||||
pub fn date(&self) -> Option<NaiveDateTime> {
|
/// Also grabs the year/month/day tuple that will be used in serialization
|
||||||
if let Some(ref d) = self.date {
|
pub fn date_to_datetime(&mut self) {
|
||||||
|
self.datetime = if let Some(ref d) = self.date {
|
||||||
if d.contains('T') {
|
if d.contains('T') {
|
||||||
DateTime::parse_from_rfc3339(&d).ok().and_then(|s| Some(s.naive_local()))
|
DateTime::parse_from_rfc3339(&d).ok().and_then(|s| Some(s.naive_local()))
|
||||||
} else {
|
} else {
|
||||||
|
@ -137,7 +147,13 @@ impl PageFrontMatter {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
};
|
||||||
|
|
||||||
|
self.datetime_tuple = if let Some(ref dt) = self.datetime {
|
||||||
|
Some((dt.year(), dt.month(), dt.day()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn order(&self) -> usize {
|
pub fn order(&self) -> usize {
|
||||||
|
@ -155,6 +171,8 @@ impl Default for PageFrontMatter {
|
||||||
title: None,
|
title: None,
|
||||||
description: None,
|
description: None,
|
||||||
date: None,
|
date: None,
|
||||||
|
datetime: None,
|
||||||
|
datetime_tuple: None,
|
||||||
draft: false,
|
draft: false,
|
||||||
slug: None,
|
slug: None,
|
||||||
path: None,
|
path: None,
|
||||||
|
|
Loading…
Reference in a new issue