Add sort/subsort functions, not working yet as intended
parent
8a7dfcd4ee
commit
43ad31d2ab
|
@ -46,7 +46,7 @@ pub struct Mailbox {
|
|||
pub folder: Folder,
|
||||
pub collection: Vec<Envelope>,
|
||||
pub threaded_collection: Vec<usize>,
|
||||
threads: Vec<Container>,
|
||||
pub threads: Vec<Container>,
|
||||
}
|
||||
|
||||
impl Mailbox {
|
||||
|
|
|
@ -53,6 +53,9 @@ pub struct Container {
|
|||
}
|
||||
|
||||
impl Container {
|
||||
pub fn date(&self) -> UnixTimestamp {
|
||||
self.date
|
||||
}
|
||||
pub fn message(&self) -> Option<usize> {
|
||||
self.message
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ pub struct MailListing {
|
|||
cursor_pos: (usize, usize, usize),
|
||||
new_cursor_pos: (usize, usize, usize),
|
||||
length: usize,
|
||||
// TODO: sorting
|
||||
sort: (SortField, SortOrder),
|
||||
subsort: (SortField, SortOrder),
|
||||
/// Cache current view.
|
||||
content: CellBuffer,
|
||||
/// If we must redraw on next redraw event
|
||||
|
@ -38,6 +39,8 @@ impl MailListing {
|
|||
cursor_pos: (0, 1, 0),
|
||||
new_cursor_pos: (0, 0, 0),
|
||||
length: 0,
|
||||
sort: (SortField::Date, SortOrder::Desc),
|
||||
subsort: (SortField::Date, SortOrder::Asc),
|
||||
content: content,
|
||||
dirty: true,
|
||||
unfocused: false,
|
||||
|
@ -99,7 +102,33 @@ impl MailListing {
|
|||
let mut indentations: Vec<bool> = Vec::with_capacity(6);
|
||||
let mut thread_idx = 0; // needed for alternate thread colors
|
||||
/* Draw threaded view. */
|
||||
let mut iter = mailbox.threaded_collection.iter().enumerate().peekable();
|
||||
let mut local_collection: Vec<usize> = mailbox.threaded_collection.clone();
|
||||
let mut threads: Vec<&Container> = mailbox.threads.iter().map(|v| v).collect();
|
||||
local_collection.sort_by(|a, b| {
|
||||
match self.sort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
mailbox.thread(*b).date().cmp(&mailbox.thread(*a).date())
|
||||
},
|
||||
(SortField::Date, SortOrder::Asc) => {
|
||||
mailbox.thread(*a).date().cmp(&mailbox.thread(*b).date())
|
||||
},
|
||||
(SortField::Subject, SortOrder::Desc) => {
|
||||
let a = mailbox.thread(*a);
|
||||
let b = mailbox.thread(*b);
|
||||
let ma = &mailbox.collection[*a.message().as_ref().unwrap()];
|
||||
let mb = &mailbox.collection[*b.message().as_ref().unwrap()];
|
||||
ma.subject().cmp(&mb.subject())
|
||||
},
|
||||
(SortField::Subject, SortOrder::Asc) => {
|
||||
let a = mailbox.thread(*a);
|
||||
let b = mailbox.thread(*b);
|
||||
let ma = &mailbox.collection[*a.message().as_ref().unwrap()];
|
||||
let mb = &mailbox.collection[*b.message().as_ref().unwrap()];
|
||||
mb.subject().cmp(&ma.subject())
|
||||
},
|
||||
}
|
||||
});
|
||||
let mut iter = local_collection.iter().enumerate().peekable();
|
||||
let len = mailbox
|
||||
.threaded_collection
|
||||
.len()
|
||||
|
@ -108,16 +137,16 @@ impl MailListing {
|
|||
.count();
|
||||
/* This is just a desugared for loop so that we can use .peek() */
|
||||
while let Some((idx, i)) = iter.next() {
|
||||
let container = mailbox.thread(*i);
|
||||
let container = threads[*i];
|
||||
let indentation = container.indentation();
|
||||
|
||||
if indentation == 0 {
|
||||
thread_idx += 1;
|
||||
}
|
||||
|
||||
assert_eq!(container.has_message(), true);
|
||||
assert!(container.has_message() == true);
|
||||
match iter.peek() {
|
||||
Some(&(_, x)) if mailbox.thread(*x).indentation() == indentation => {
|
||||
Some(&(_, x)) if threads[*x].indentation() == indentation => {
|
||||
indentations.pop();
|
||||
indentations.push(true);
|
||||
}
|
||||
|
@ -164,11 +193,11 @@ impl MailListing {
|
|||
}
|
||||
|
||||
match iter.peek() {
|
||||
Some(&(_, x)) if mailbox.thread(*x).indentation() > indentation => {
|
||||
Some(&(_, x)) if threads[*x].indentation() > indentation => {
|
||||
indentations.push(false);
|
||||
}
|
||||
Some(&(_, x)) if mailbox.thread(*x).indentation() < indentation => {
|
||||
for _ in 0..(indentation - mailbox.thread(*x).indentation()) {
|
||||
Some(&(_, x)) if threads[*x].indentation() < indentation => {
|
||||
for _ in 0..(indentation - threads[*x].indentation()) {
|
||||
indentations.pop();
|
||||
}
|
||||
}
|
||||
|
@ -661,7 +690,13 @@ impl Component for MailListing {
|
|||
self.refresh_mailbox(context);
|
||||
return;
|
||||
},
|
||||
//_ => {},
|
||||
Action::Sort(field, order) => {
|
||||
self.sort = (field.clone(), order.clone());
|
||||
self.dirty = true;
|
||||
self.refresh_mailbox(context);
|
||||
return;
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,65 @@
|
|||
* User actions that need to be handled by the UI
|
||||
*/
|
||||
|
||||
#[derive(Debug)]
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MailListingAction {
|
||||
ToggleThreaded,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SortOrder {
|
||||
Asc,
|
||||
Desc,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SortField {
|
||||
Subject,
|
||||
Date,
|
||||
}
|
||||
|
||||
|
||||
impl FromStr for SortField {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
eprintln!("sortfield from_str {}", s);
|
||||
match s.trim() {
|
||||
"subject" | "s" | "sub" | "sbj" | "subj" => {
|
||||
eprintln!("parsed: subject");
|
||||
}
|
||||
"date" | "d" => {
|
||||
eprintln!("parsed date");
|
||||
}
|
||||
_ => {
|
||||
eprintln!("error in parse");
|
||||
}
|
||||
}
|
||||
match s.trim() {
|
||||
"subject" | "s" | "sub" | "sbj" | "subj" => Ok(SortField::Subject),
|
||||
"date" | "d" => Ok(SortField::Date),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for SortOrder {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
eprintln!("sortoder from_str {}", s);
|
||||
match s.trim() {
|
||||
"asc" => Ok(SortOrder::Asc),
|
||||
"desc" => Ok(SortOrder::Desc),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Action {
|
||||
MailListing(MailListingAction),
|
||||
ViewMailbox(usize),
|
||||
Sort(SortField, SortOrder),
|
||||
SubSort(SortField, SortOrder),
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*! A parser module for user commands passed through the Ex mode.
|
||||
*/
|
||||
use nom::{digit, };
|
||||
use nom::{digit, not_line_ending};
|
||||
use std;
|
||||
pub mod actions;
|
||||
pub use actions::*;
|
||||
|
@ -14,15 +14,40 @@ named!(
|
|||
)
|
||||
);
|
||||
|
||||
named!(sortfield<SortField>,
|
||||
map_res!(
|
||||
map_res!(take_until_s!(" "), std::str::from_utf8),
|
||||
std::str::FromStr::from_str));
|
||||
|
||||
|
||||
named!(sortorder<SortOrder>,
|
||||
map_res!(
|
||||
map_res!(call!(not_line_ending), std::str::from_utf8),
|
||||
std::str::FromStr::from_str));
|
||||
|
||||
|
||||
|
||||
named!(goto<Action>,
|
||||
preceded!(tag!("b "),
|
||||
map!(call!(usize_c), |v| Action::ViewMailbox(v))
|
||||
));
|
||||
|
||||
//named!(sort<&str>,
|
||||
// preceded!(tag!("sort "),
|
||||
// map_res!(call!(alpha), std::str::from_utf8))
|
||||
// );
|
||||
named!(subsort<Action>, do_parse!(
|
||||
tag!("subsort ") >>
|
||||
p: pair!(sortfield,sortorder) >>
|
||||
(
|
||||
Action::SubSort(p.0, p.1)
|
||||
|
||||
)
|
||||
));
|
||||
named!(sort<Action>, do_parse!(
|
||||
tag!("sort ") >>
|
||||
p: separated_pair!(sortfield,tag!(" "), sortorder) >>
|
||||
(
|
||||
Action::Sort(p.0, p.1)
|
||||
|
||||
)
|
||||
));
|
||||
|
||||
named!(threaded<Action>,
|
||||
map!(ws!(tag!("threaded")), |_| Action::MailListing(MailListingAction::ToggleThreaded)));
|
||||
|
@ -30,6 +55,6 @@ named!(toggle<Action>,
|
|||
preceded!(tag!("toggle "),
|
||||
alt_complete!( threaded )));
|
||||
|
||||
named!(pub parse_command<Action>,
|
||||
alt_complete!( goto | toggle)
|
||||
named!(pub parse_command<Action>,
|
||||
alt_complete!( goto | toggle | sort | subsort)
|
||||
);
|
||||
|
|
|
@ -313,7 +313,9 @@ impl<W: Write> State<W> {
|
|||
}
|
||||
/// Convert user commands to actions/method calls.
|
||||
fn parse_command(&mut self, cmd: String) {
|
||||
eprintln!("cmd is {}", cmd);
|
||||
let result = parse_command(&cmd.as_bytes()).to_full_result();
|
||||
eprintln!("rseult is {:?}", result);
|
||||
|
||||
if let Ok(v) = result {
|
||||
self.rcv_event(UIEvent { id: 0, event_type: UIEventType::Action(v) });
|
||||
|
@ -399,7 +401,6 @@ impl<W: Write> State<W> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn try_wait_on_child(&mut self) -> Option<bool> {
|
||||
if {
|
||||
match self.child {
|
||||
|
|
Loading…
Reference in New Issue