ui: print menu entries in order

FolderNode is a tree structure to represent the sorted or user defined
order inside the Account type
embed
Manos Pitsidianakis 2019-05-07 21:52:11 +03:00
parent 9afeb648f7
commit c26dd0685b
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
3 changed files with 57 additions and 17 deletions

View File

@ -546,20 +546,11 @@ impl Listing {
let mut children: Vec<FolderHash> = entries[&folder_idx].children().to_vec();
children
.sort_unstable_by(|a, b| folders_order[a].partial_cmp(&folders_order[b]).unwrap());
for child in entries[&folder_idx].children().iter() {
for child in children {
let len = s.len();
s.insert_str(len, &format!("{} ", depth));
push(depth, ' ');
print(
*child,
depth,
inc,
entries,
folders_order,
s,
index,
context,
);
print(child, depth, inc, entries, folders_order, s, index, context);
pop(depth);
}
}

View File

@ -62,6 +62,7 @@ pub struct Account {
name: String,
pub(crate) folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
pub(crate) folders_order: Vec<FolderHash>,
tree: Vec<FolderNode>,
sent_folder: Option<usize>,
pub(crate) address_book: AddressBook,
@ -123,13 +124,19 @@ impl<'a> Iterator for MailboxIterator<'a> {
}
}
#[derive(Debug, Default)]
struct FolderNode {
hash: FolderHash,
kids: Vec<FolderNode>,
}
impl Account {
pub fn new(name: String, settings: AccountConf, map: &Backends, notify_fn: NotifyFn) -> Self {
let mut backend = map.get(settings.account().format())(settings.account());
let mut ref_folders: FnvHashMap<FolderHash, Folder> = backend.folders();
let mut folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>> =
FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default());
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(folders.len());
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(ref_folders.len());
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
let notify_fn = Arc::new(notify_fn);
@ -144,14 +151,29 @@ impl Account {
}
}
let mut stack: StackVec<FolderHash> = StackVec::new();
let mut tree: Vec<FolderNode> = Vec::new();
for (h, f) in ref_folders.iter() {
if f.parent().is_none() {
folders_order.push(f.hash());
fn rec(h: FolderHash, ref_folders: &FnvHashMap<FolderHash, Folder>) -> FolderNode {
let mut node = FolderNode {
hash: h,
kids: Vec::new(),
};
for &c in ref_folders[&h].children() {
node.kids.push(rec(c, ref_folders));
}
node
};
tree.push(rec(*h, &ref_folders));
for &c in f.children() {
let k = FolderNode {
hash: c,
kids: Vec::new(),
};
stack.push(c);
}
while let Some(next) = stack.pop() {
folders_order.push(next);
for c in ref_folders[&next].children() {
stack.push(*c);
}
@ -163,6 +185,20 @@ impl Account {
Account::new_worker(f.clone(), &mut backend, notify_fn.clone()),
);
}
tree.sort_unstable_by_key(|f| ref_folders[&f.hash].name());
{
//FIXME: NLL
let mut stack: StackVec<Option<&FolderNode>> = StackVec::new();
for n in tree.iter_mut() {
folders_order.push(n.hash);
n.kids.sort_unstable_by_key(|f| ref_folders[&f.hash].name());
stack.extend(n.kids.iter().rev().map(|r| Some(r)));
while let Some(Some(next)) = stack.pop() {
folders_order.push(next.hash);
stack.extend(next.kids.iter().rev().map(|r| Some(r)));
}
}
}
let data_dir = xdg::BaseDirectories::with_profile("meli", &name).unwrap();
let address_book = if let Ok(data) = data_dir.place_data_file("addressbook") {
@ -185,6 +221,7 @@ impl Account {
name,
folders,
folders_order,
tree,
address_book,
sent_folder: None,
workers,

View File

@ -30,6 +30,7 @@ use melib::backends::FolderHash;
use melib::{EnvelopeHash, RefreshEvent};
use std;
use std::fmt;
use std::iter::Extend;
use std::ops::Index;
use std::thread;
use uuid::Uuid;
@ -132,7 +133,7 @@ pub struct Notification {
#[derive(Debug)]
pub(crate) struct StackVec<T: Default + Copy + std::fmt::Debug> {
len: usize,
array: [T; 8],
array: [T; 32],
heap_vec: Vec<T>,
}
@ -140,14 +141,14 @@ impl<T: Default + Copy + std::fmt::Debug> StackVec<T> {
pub(crate) fn new() -> Self {
StackVec {
len: 0,
array: [T::default(); 8],
array: [T::default(); 32],
heap_vec: Vec::new(),
}
}
pub(crate) fn push(&mut self, ind: T) {
if self.len == self.array.len() {
if self.heap_vec.is_empty() {
self.heap_vec.reserve(16);
self.heap_vec.reserve(32);
for _ in 0..8 {
self.heap_vec.push(T::default());
}
@ -193,3 +194,14 @@ impl<T: Default + Copy + std::fmt::Debug> Index<usize> for StackVec<T> {
}
}
}
impl<T: Default + Copy + std::fmt::Debug> Extend<T> for StackVec<T> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
for elem in iter {
self.push(elem);
}
}
}