Break sorting ties by a-z ordering

Closes #259
This commit is contained in:
Vincent Prouillet 2018-03-17 18:07:59 +01:00
parent 3a2dab5974
commit 00729581f9
2 changed files with 73 additions and 21 deletions

View file

@ -1,3 +1,5 @@
use std::cmp::Ordering;
use rayon::prelude::*; use rayon::prelude::*;
use page::Page; use page::Page;
@ -24,9 +26,36 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
}); });
match sort_by { match sort_by {
SortBy::Date => can_be_sorted.par_sort_unstable_by(|a, b| b.meta.date().unwrap().cmp(&a.meta.date().unwrap())), SortBy::Date => {
SortBy::Order => can_be_sorted.par_sort_unstable_by(|a, b| b.meta.order().cmp(&a.meta.order())), can_be_sorted.par_sort_unstable_by(|a, b| {
SortBy::Weight => can_be_sorted.par_sort_unstable_by(|a, b| a.meta.weight().cmp(&b.meta.weight())), let ord = b.meta.date().unwrap().cmp(&a.meta.date().unwrap());
if ord == Ordering::Equal {
a.permalink.cmp(&b.permalink)
} else {
ord
}
})
},
SortBy::Order => {
can_be_sorted.par_sort_unstable_by(|a, b| {
let ord = b.meta.order().cmp(&a.meta.order());
if ord == Ordering::Equal {
a.permalink.cmp(&b.permalink)
} else {
ord
}
})
},
SortBy::Weight => {
can_be_sorted.par_sort_unstable_by(|a, b| {
let ord = a.meta.weight().cmp(&b.meta.weight());
if ord == Ordering::Equal {
a.permalink.cmp(&b.permalink)
} else {
ord
}
})
},
_ => unreachable!() _ => unreachable!()
}; };
@ -108,10 +137,13 @@ mod tests {
Page::new("content/hello.md", front_matter) Page::new("content/hello.md", front_matter)
} }
fn create_page_with_order(order: usize) -> Page { fn create_page_with_order(order: usize, filename: &str) -> Page {
let mut front_matter = PageFrontMatter::default(); let mut front_matter = PageFrontMatter::default();
front_matter.order = Some(order); front_matter.order = Some(order);
Page::new("content/hello.md", front_matter) let mut p = Page::new("content/".to_string() + filename, front_matter);
// Faking a permalink to test sorting with equal order
p.permalink = filename.to_string();
p
} }
fn create_draft_page_with_order(order: usize) -> Page { fn create_draft_page_with_order(order: usize) -> Page {
@ -144,17 +176,34 @@ mod tests {
#[test] #[test]
fn can_sort_by_order() { fn can_sort_by_order() {
let input = vec![ let input = vec![
create_page_with_order(2), create_page_with_order(2, "hello.md"),
create_page_with_order(3), create_page_with_order(3, "hello2.md"),
create_page_with_order(1), create_page_with_order(1, "hello3.md"),
]; ];
let (pages, _) = sort_pages(input, SortBy::Order); let (pages, _) = sort_pages(input, SortBy::Order);
// Should be sorted by date // Should be sorted by order
assert_eq!(pages[0].clone().meta.order.unwrap(), 3); assert_eq!(pages[0].clone().meta.order.unwrap(), 3);
assert_eq!(pages[1].clone().meta.order.unwrap(), 2); assert_eq!(pages[1].clone().meta.order.unwrap(), 2);
assert_eq!(pages[2].clone().meta.order.unwrap(), 1); assert_eq!(pages[2].clone().meta.order.unwrap(), 1);
} }
#[test]
fn can_sort_by_order_uses_permalink_to_break_ties() {
let input = vec![
create_page_with_order(3, "b.md"),
create_page_with_order(3, "a.md"),
create_page_with_order(3, "c.md"),
];
let (pages, _) = sort_pages(input, SortBy::Order);
// Should be sorted by order
assert_eq!(pages[0].clone().meta.order.unwrap(), 3);
assert_eq!(pages[0].clone().permalink, "a.md");
assert_eq!(pages[1].clone().meta.order.unwrap(), 3);
assert_eq!(pages[1].clone().permalink, "b.md");
assert_eq!(pages[2].clone().meta.order.unwrap(), 3);
assert_eq!(pages[2].clone().permalink, "c.md");
}
#[test] #[test]
fn can_sort_by_weight() { fn can_sort_by_weight() {
let input = vec![ let input = vec![
@ -163,7 +212,7 @@ mod tests {
create_page_with_weight(1), create_page_with_weight(1),
]; ];
let (pages, _) = sort_pages(input, SortBy::Weight); let (pages, _) = sort_pages(input, SortBy::Weight);
// Should be sorted by date // Should be sorted by weight
assert_eq!(pages[0].clone().meta.weight.unwrap(), 1); assert_eq!(pages[0].clone().meta.weight.unwrap(), 1);
assert_eq!(pages[1].clone().meta.weight.unwrap(), 2); assert_eq!(pages[1].clone().meta.weight.unwrap(), 2);
assert_eq!(pages[2].clone().meta.weight.unwrap(), 3); assert_eq!(pages[2].clone().meta.weight.unwrap(), 3);
@ -172,9 +221,9 @@ mod tests {
#[test] #[test]
fn can_sort_by_none() { fn can_sort_by_none() {
let input = vec![ let input = vec![
create_page_with_order(2), create_page_with_order(2, "a.md"),
create_page_with_order(3), create_page_with_order(3, "a.md"),
create_page_with_order(1), create_page_with_order(1, "a.md"),
]; ];
let (pages, _) = sort_pages(input, SortBy::None); let (pages, _) = sort_pages(input, SortBy::None);
// Should be sorted by date // Should be sorted by date
@ -186,8 +235,8 @@ mod tests {
#[test] #[test]
fn ignore_page_with_missing_field() { fn ignore_page_with_missing_field() {
let input = vec![ let input = vec![
create_page_with_order(2), create_page_with_order(2, "a.md"),
create_page_with_order(3), create_page_with_order(3, "a.md"),
create_page_with_date("2019-01-01"), create_page_with_date("2019-01-01"),
]; ];
let (pages, unsorted) = sort_pages(input, SortBy::Order); let (pages, unsorted) = sort_pages(input, SortBy::Order);
@ -198,9 +247,9 @@ mod tests {
#[test] #[test]
fn can_populate_previous_and_next_pages() { fn can_populate_previous_and_next_pages() {
let input = vec![ let input = vec![
create_page_with_order(1), create_page_with_order(1, "a.md"),
create_page_with_order(2), create_page_with_order(2, "b.md"),
create_page_with_order(3), create_page_with_order(3, "a.md"),
]; ];
let pages = populate_previous_and_next_pages(&input); let pages = populate_previous_and_next_pages(&input);
@ -222,9 +271,9 @@ mod tests {
fn can_populate_previous_and_next_pages_skip_drafts() { fn can_populate_previous_and_next_pages_skip_drafts() {
let input = vec![ let input = vec![
create_draft_page_with_order(0), create_draft_page_with_order(0),
create_page_with_order(1), create_page_with_order(1, "a.md"),
create_page_with_order(2), create_page_with_order(2, "b.md"),
create_page_with_order(3), create_page_with_order(3, "c.md"),
create_draft_page_with_order(4), create_draft_page_with_order(4),
]; ];
let pages = populate_previous_and_next_pages(&input); let pages = populate_previous_and_next_pages(&input);

View file

@ -78,6 +78,9 @@ is enabled by setting the `sort_by` front-matter variable.
Any page that cannot be sorted, for example if missing the date variable while sorting by `date`, will be ignored and Any page that cannot be sorted, for example if missing the date variable while sorting by `date`, will be ignored and
won't be rendered. The terminal will warn you if this is happening. won't be rendered. The terminal will warn you if this is happening.
If several pages have the same date/weight/order, their permalink will be used to break the tie following
an alphabetical order.
### `date` ### `date`
This will sort all pages by their `date` field, from the most recent to the oldest. This will sort all pages by their `date` field, from the most recent to the oldest.