diff --git a/Cargo.lock b/Cargo.lock
index 14d7b487..f67bb3b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -771,6 +771,7 @@ dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"text_processing 0.4.1",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1553,8 +1554,11 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.0.0"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "sourcefile"
@@ -1860,6 +1864,7 @@ dependencies = [
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"text_processing 0.4.1",
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1889,7 +1894,7 @@ name = "unicode-normalization"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2298,7 +2303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
-"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
+"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
diff --git a/melib/Cargo.toml b/melib/Cargo.toml
index e7a40533..881e932c 100644
--- a/melib/Cargo.toml
+++ b/melib/Cargo.toml
@@ -27,6 +27,7 @@ text_processing = { path = "../text_processing", version = "*", optional= true }
libc = {version = "0.2.59", features = ["extra_traits",]}
reqwest = { version ="0.10.0-alpha.2", optional=true, features = ["json", "blocking" ]}
serde_json = { version = "1.0", optional = true, features = ["raw_value",] }
+smallvec = { version = "1.1.0", features = ["serde", ] }
[features]
default = ["unicode_algorithms", "imap_backend", "maildir_backend", "mbox_backend", "vcard"]
diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs
index dd4aad88..de694f53 100644
--- a/melib/src/backends/imap.rs
+++ b/melib/src/backends/imap.rs
@@ -19,6 +19,7 @@
* along with meli. If not, see .
*/
+use smallvec::SmallVec;
#[macro_use]
mod protocol_parser;
pub use protocol_parser::{UntaggedResponse::*, *};
@@ -677,7 +678,7 @@ impl ImapType {
&self,
query: String,
folder_hash: FolderHash,
- ) -> Result> {
+ ) -> Result> {
let folders_lck = self.folders.read()?;
let mut response = String::with_capacity(8 * 1024);
let mut conn = self.connection.lock()?;
@@ -692,7 +693,7 @@ impl ImapType {
if l.starts_with("* SEARCH") {
use std::iter::FromIterator;
let uid_index = self.uid_store.uid_index.lock()?;
- return Ok(crate::structs::StackVec::from_iter(
+ return Ok(SmallVec::from_iter(
l["* SEARCH".len()..]
.trim()
.split_whitespace()
diff --git a/melib/src/backends/jmap/protocol.rs b/melib/src/backends/jmap/protocol.rs
index 6057a2e9..10bb7092 100644
--- a/melib/src/backends/jmap/protocol.rs
+++ b/melib/src/backends/jmap/protocol.rs
@@ -21,9 +21,9 @@
use super::folder::JmapFolder;
use super::*;
-use crate::structs::StackVec;
use serde::Serialize;
use serde_json::{json, Value};
+use smallvec::SmallVec;
use std::collections::hash_map::DefaultHasher;
use std::convert::TryFrom;
use std::hash::{Hash, Hasher};
@@ -327,10 +327,10 @@ pub fn get(
}
tag_hash
})
- .collect::>();
+ .collect::>();
(tags, obj.id.clone(), obj.blob_id.clone())
})
- .collect::, Id, Id)>>();
+ .collect::, Id, Id)>>();
drop(tag_lck);
let mut ret = list
.into_iter()
diff --git a/melib/src/backends/notmuch.rs b/melib/src/backends/notmuch.rs
index 8356c840..66666797 100644
--- a/melib/src/backends/notmuch.rs
+++ b/melib/src/backends/notmuch.rs
@@ -1,3 +1,24 @@
+/*
+ * meli - notmuch backend
+ *
+ * Copyright 2019 - 2020 Manos Pitsidianakis
+ *
+ * This file is part of meli.
+ *
+ * meli is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * meli is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with meli. If not, see .
+ */
+
use crate::async_workers::{Async, AsyncBuilder, AsyncStatus, WorkContext};
use crate::backends::FolderHash;
use crate::backends::{
@@ -8,8 +29,8 @@ use crate::conf::AccountSettings;
use crate::email::{Envelope, EnvelopeHash, Flag};
use crate::error::{MeliError, Result};
use crate::shellexpand::ShellExpandTrait;
-use crate::structs::StackVec;
use fnv::FnvHashMap;
+use smallvec::SmallVec;
use std::collections::hash_map::DefaultHasher;
use std::collections::BTreeMap;
use std::ffi::{CStr, CString};
@@ -229,7 +250,7 @@ impl NotmuchDb {
Ok(())
}
- pub fn search(&self, query_s: &str) -> Result> {
+ pub fn search(&self, query_s: &str) -> Result> {
let database_lck = self.database.inner.read().unwrap();
let query_str = std::ffi::CString::new(query_s).unwrap();
let query: *mut notmuch_query_t =
@@ -247,7 +268,7 @@ impl NotmuchDb {
}
assert!(!messages.is_null());
let iter = MessageIterator { messages };
- let mut ret = StackVec::new();
+ let mut ret = SmallVec::new();
for message in iter {
let fs_path = unsafe { notmuch_message_get_filename(message) };
let c_str = unsafe { CStr::from_ptr(fs_path) };
diff --git a/melib/src/collection.rs b/melib/src/collection.rs
index 28c9cd32..a5fc0095 100644
--- a/melib/src/collection.rs
+++ b/melib/src/collection.rs
@@ -1,5 +1,6 @@
use super::*;
use crate::backends::FolderHash;
+use smallvec::SmallVec;
use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
@@ -160,7 +161,7 @@ impl Collection {
mut new_envelopes: FnvHashMap,
folder_hash: FolderHash,
sent_folder: Option,
- ) -> Option> {
+ ) -> Option> {
self.sent_folder = sent_folder;
for (h, e) in new_envelopes.iter() {
self.message_ids.insert(e.message_id().raw().to_vec(), *h);
@@ -198,7 +199,7 @@ impl Collection {
});
}
- let mut ret = StackVec::new();
+ let mut ret = SmallVec::new();
let keys = threads.keys().cloned().collect::>();
for t_fh in keys {
if t_fh == folder_hash {
diff --git a/melib/src/datetime.rs b/melib/src/datetime.rs
index 7c56686f..0c89925b 100644
--- a/melib/src/datetime.rs
+++ b/melib/src/datetime.rs
@@ -61,7 +61,7 @@ pub fn timestamp_to_string(timestamp: UnixTimestamp, fmt: Option<&str>) -> Strin
};
let s: CString;
unsafe {
- let mut vec: Vec = vec![0; 256];
+ let mut vec: [u8; 256] = [0; 256];
let ret = strftime(
vec.as_mut_ptr() as *mut _,
256,
diff --git a/melib/src/email.rs b/melib/src/email.rs
index cab8565e..1faff060 100644
--- a/melib/src/email.rs
+++ b/melib/src/email.rs
@@ -43,6 +43,7 @@ use crate::datetime::UnixTimestamp;
use crate::error::{MeliError, Result};
use crate::thread::ThreadHash;
+use smallvec::SmallVec;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher;
@@ -132,7 +133,7 @@ pub struct Envelope {
flags: Flag,
has_attachments: bool,
- labels: crate::structs::StackVec,
+ labels: SmallVec<[u64; 8]>,
}
impl fmt::Debug for Envelope {
@@ -170,7 +171,7 @@ impl Envelope {
hash,
has_attachments: false,
flags: Flag::default(),
- labels: crate::structs::StackVec::new(),
+ labels: SmallVec::new(),
}
}
@@ -609,11 +610,11 @@ impl Envelope {
self.has_attachments
}
- pub fn labels(&self) -> &crate::structs::StackVec {
+ pub fn labels(&self) -> &SmallVec<[u64; 8]> {
&self.labels
}
- pub fn labels_mut(&mut self) -> &mut crate::structs::StackVec {
+ pub fn labels_mut(&mut self) -> &mut SmallVec<[u64; 8]> {
&mut self.labels
}
}
diff --git a/melib/src/email/list_management.rs b/melib/src/email/list_management.rs
index c4744367..93a14d3d 100644
--- a/melib/src/email/list_management.rs
+++ b/melib/src/email/list_management.rs
@@ -18,9 +18,10 @@
* You should have received a copy of the GNU General Public License
* along with meli. If not, see .
*/
+
use super::parser;
use super::Envelope;
-use crate::StackVec;
+use smallvec::SmallVec;
use std::convert::From;
#[derive(Debug, Copy)]
@@ -46,7 +47,7 @@ impl<'a> From<&'a [u8]> for ListAction<'a> {
}
impl<'a> ListAction<'a> {
- pub fn parse_options_list(input: &'a [u8]) -> Option>> {
+ pub fn parse_options_list(input: &'a [u8]) -> Option; 4]>> {
parser::angle_bracket_delimeted_list(input)
.map(|mut vec| {
/* Prefer email options first, since this _is_ a mail client after all and it's
@@ -61,20 +62,13 @@ impl<'a> ListAction<'a> {
vec.into_iter()
.map(|elem| ListAction::from(elem))
- .collect::>>()
+ .collect::; 4]>>()
})
.to_full_result()
.ok()
}
}
-/* Required for StackVec's place holder elements, never actually used */
-impl<'a> Default for ListAction<'a> {
- fn default() -> Self {
- ListAction::Email(b"")
- }
-}
-
impl<'a> Clone for ListAction<'a> {
fn clone(&self) -> Self {
match self {
@@ -88,8 +82,8 @@ impl<'a> Clone for ListAction<'a> {
pub struct ListActions<'a> {
pub id: Option<&'a str>,
pub archive: Option<&'a str>,
- pub post: Option>>,
- pub unsubscribe: Option>>,
+ pub post: Option; 4]>>,
+ pub unsubscribe: Option; 4]>>,
}
pub fn list_id_header<'a>(envelope: &'a Envelope) -> Option<&'a str> {
diff --git a/melib/src/lib.rs b/melib/src/lib.rs
index 36cc0e72..468bfc14 100644
--- a/melib/src/lib.rs
+++ b/melib/src/lib.rs
@@ -123,8 +123,6 @@ pub mod mailbox;
pub mod thread;
pub use crate::email::*;
pub use crate::thread::*;
-mod structs;
-pub use self::structs::*;
pub mod parsec;
#[macro_use]
diff --git a/melib/src/structs.rs b/melib/src/structs.rs
deleted file mode 100644
index f4d1b427..00000000
--- a/melib/src/structs.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * meli - melib crate.
- *
- * Copyright 2019 Manos Pitsidianakis
- *
- * This file is part of meli.
- *
- * meli is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * meli is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with meli. If not, see .
- */
-
-use std::iter::{Extend, FromIterator};
-use std::ops::Index;
-use std::ops::IndexMut;
-
-const STACK_VEC_CAPACITY: usize = 32;
-#[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct StackVec {
- len: usize,
- array: [T; STACK_VEC_CAPACITY],
- heap_vec: Vec,
-}
-
-impl StackVec {
- pub fn new() -> Self {
- StackVec {
- len: 0,
- array: [T::default(); STACK_VEC_CAPACITY],
- heap_vec: Vec::new(),
- }
- }
- pub fn push(&mut self, ind: T) {
- if self.len == self.array.len() {
- if self.heap_vec.is_empty() {
- self.heap_vec.reserve(STACK_VEC_CAPACITY);
- for _ in 0..STACK_VEC_CAPACITY {
- self.heap_vec.push(T::default());
- }
- }
- self.heap_vec[0..STACK_VEC_CAPACITY].copy_from_slice(&self.array);
- self.heap_vec.push(ind);
- } else if self.len > self.array.len() {
- self.heap_vec.push(ind);
- } else {
- self.array[self.len] = ind;
- }
- self.len += 1;
- }
- pub fn pop(&mut self) -> Option {
- if self.len == 0 {
- return None;
- }
- if self.len > self.array.len() {
- self.len -= 1;
- self.heap_vec.pop()
- } else {
- let ret = self.array[self.len - 1];
- self.len -= 1;
- Some(ret)
- }
- }
- pub fn len(&self) -> usize {
- self.len
- }
- pub fn is_empty(&self) -> bool {
- self.len == 0
- }
- pub fn iter(&self) -> StackVecIter {
- StackVecIter {
- stack: &self,
- range: 0..self.len,
- }
- }
- pub fn remove(&mut self, i: usize) -> T {
- if self.len > self.array.len() {
- self.len -= 1;
- self.heap_vec.remove(i)
- } else {
- let ret = std::mem::replace(&mut self.array[i], T::default());
- self.len -= 1;
- for i in i..self.len {
- self.array[i] = self.array[i + 1];
- }
- ret
- }
- }
-
- pub fn set(&mut self, i: usize, val: T) {
- debug_assert!(i < self.len);
- if self.len > self.array.len() {
- self.heap_vec[i] = val;
- if i < self.array.len() {
- self.array[i] = val;
- }
- } else {
- self.array[i] = val;
- }
- }
-
- pub fn clear(&mut self) {
- self.len = 0;
- }
-}
-
-pub struct StackVecIter<'a, T: Default + Copy + std::fmt::Debug> {
- stack: &'a StackVec,
- range: std::ops::Range,
-}
-
-impl<'a, T: Default + Copy + std::fmt::Debug> Iterator for StackVecIter<'a, T> {
- type Item = &'a T;
- fn next(&mut self) -> Option<&'a T> {
- if self.range.len() == 0 {
- None
- } else {
- let idx = self.range.start;
- self.range.start += 1;
- Some(&self.stack[idx])
- }
- }
-}
-impl<'a, T: Default + Copy + std::fmt::Debug> std::iter::DoubleEndedIterator
- for StackVecIter<'a, T>
-{
- fn next_back(&mut self) -> Option<&'a T> {
- if self.range.len() == 0 {
- None
- } else {
- let idx = self.range.end - 1;
- self.range.end -= 1;
- Some(&self.stack[idx])
- }
- }
-}
-
-impl Index for StackVec {
- type Output = T;
-
- fn index(&self, idx: usize) -> &T {
- if self.len > self.array.len() {
- &self.heap_vec[idx]
- } else {
- &self.array[idx]
- }
- }
-}
-
-impl IndexMut for StackVec {
- fn index_mut(&mut self, idx: usize) -> &mut T {
- if self.len > self.array.len() {
- &mut self.heap_vec[idx]
- } else {
- &mut self.array[idx]
- }
- }
-}
-
-impl Extend for StackVec {
- fn extend(&mut self, iter: I)
- where
- I: IntoIterator- ,
- {
- for elem in iter {
- self.push(elem);
- }
- }
-}
-
-impl FromIterator for StackVec {
- fn from_iter>(iter: I) -> Self {
- let mut c = StackVec::new();
-
- for i in iter {
- c.push(i);
- }
-
- c
- }
-}
-
-pub struct StackVecIterOwned(StackVec);
-impl IntoIterator for StackVec {
- type Item = T;
- type IntoIter = StackVecIterOwned;
-
- fn into_iter(self) -> Self::IntoIter {
- StackVecIterOwned(self)
- }
-}
-
-impl<'a, T: Default + Copy + std::fmt::Debug> IntoIterator for &'a StackVec {
- type Item = &'a T;
- type IntoIter = StackVecIter<'a, T>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl Iterator for StackVecIterOwned {
- type Item = T;
- fn next(&mut self) -> Option {
- if self.0.is_empty() {
- None
- } else {
- Some(self.0.remove(0))
- }
- }
-}
-impl std::iter::DoubleEndedIterator for StackVecIterOwned {
- fn next_back(&mut self) -> Option {
- if self.0.is_empty() {
- None
- } else {
- self.0.pop()
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_stackvec() {
- let mut stack = StackVec::from_iter(0..4 * STACK_VEC_CAPACITY);
- let mut ctr = 0;
- assert!(stack.iter().all(|&x| {
- let ret = x == ctr;
- ctr += 1;
- ret
- }));
- for _ in 0..(3 * STACK_VEC_CAPACITY) + 1 {
- stack.pop();
- }
- ctr = 0;
- assert!(stack.iter().all(|&x| {
- let ret = x == ctr;
- ctr += 1;
- ret
- }));
- }
-}
diff --git a/melib/src/thread.rs b/melib/src/thread.rs
index 9c8fdbfe..0b3464cb 100644
--- a/melib/src/thread.rs
+++ b/melib/src/thread.rs
@@ -35,7 +35,6 @@
use crate::datetime::UnixTimestamp;
use crate::email::parser::BytesExt;
use crate::email::*;
-use crate::structs::StackVec;
#[cfg(feature = "unicode_algorithms")]
use text_processing::grapheme_clusters::*;
@@ -53,6 +52,8 @@ use std::str::FromStr;
use std::string::ToString;
use std::sync::{Arc, RwLock};
+use smallvec::SmallVec;
+
type Envelopes = Arc>>;
#[derive(PartialEq, Hash, Eq, Copy, Clone, Serialize, Deserialize, Default)]
@@ -279,7 +280,7 @@ impl FromStr for SortOrder {
pub struct ThreadsIterator<'a> {
pos: usize,
- stack: StackVec,
+ stack: SmallVec<[usize; 16]>,
root_tree: Ref<'a, Vec>,
thread_nodes: &'a FnvHashMap,
}
@@ -332,7 +333,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
pub struct ThreadIterator<'a> {
init_pos: usize,
pos: usize,
- stack: StackVec,
+ stack: SmallVec<[usize; 16]>,
root_tree: Ref<'a, Vec>,
thread_nodes: &'a FnvHashMap,
}
@@ -724,7 +725,7 @@ impl Threads {
pub fn threads_iter(&self) -> ThreadsIterator {
ThreadsIterator {
pos: 0,
- stack: StackVec::new(),
+ stack: SmallVec::new(),
root_tree: self.tree_index.borrow(),
thread_nodes: &self.thread_nodes,
}
@@ -734,7 +735,7 @@ impl Threads {
ThreadIterator {
init_pos: index,
pos: index,
- stack: StackVec::new(),
+ stack: SmallVec::new(),
root_tree: self.tree_index.borrow(),
thread_nodes: &self.thread_nodes,
}
diff --git a/src/bin.rs b/src/bin.rs
index b41f6825..d031c92a 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -256,7 +256,7 @@ fn run_app() -> Result<()> {
'inner: loop {
/* Check if any components have sent reply events to State. */
- let events: Vec = state.context.replies();
+ let events: ui::smallvec::SmallVec<[UIEvent; 8]> = state.context.replies();
for e in events {
state.rcv_event(e);
}
diff --git a/testing/src/linebreak.rs b/testing/src/linebreak.rs
index 1d3eedf0..ec93603c 100644
--- a/testing/src/linebreak.rs
+++ b/testing/src/linebreak.rs
@@ -1,6 +1,5 @@
extern crate melib;
use melib::Result;
-use melib::StackVec;
extern crate text_processing;
use text_processing::line_break::*;
@@ -14,14 +13,14 @@ fn cost(i: usize, j: usize, width: usize, minima: &Vec, offsets: &Vec,
- columns: &mut StackVec,
+ rows: &mut Vec,
+ columns: &mut Vec,
minima: &mut Vec,
breaks: &mut Vec,
width: usize,
offsets: &Vec,
) {
- let mut stack = StackVec::new();
+ let mut stack = Vec::new();
let mut i = 0;
while i < rows.len() {
if stack.len() > 0 {
@@ -46,7 +45,7 @@ fn smawk(
let mut odd_columns = columns.iter().skip(1).step_by(2).cloned().collect();
smawk(rows, &mut odd_columns, minima, breaks, width, offsets);
for (i, o) in odd_columns.into_iter().enumerate() {
- columns.set(2 * i + 1, o);
+ columns[2 * i + 1] = o;
}
}
let mut i = 0;
diff --git a/ui/Cargo.toml b/ui/Cargo.toml
index 020ea1ab..41de817a 100644
--- a/ui/Cargo.toml
+++ b/ui/Cargo.toml
@@ -30,6 +30,7 @@ rusqlite = {version = "0.20.0", optional =true }
rmp = "^0.8"
rmpv = { version = "^0.4.2", features=["with-serde",] }
rmp-serde = "^0.14.0"
+smallvec = { version = "1.1.0", features = ["serde", ] }
[features]
default = ["sqlite3"]
diff --git a/ui/src/cache.rs b/ui/src/cache.rs
index afb542e1..29f187b8 100644
--- a/ui/src/cache.rs
+++ b/ui/src/cache.rs
@@ -25,7 +25,7 @@ use melib::{
backends::{FolderHash, MailBackend},
email::EnvelopeHash,
thread::{SortField, SortOrder},
- Result, StackVec,
+ Result,
};
use std::sync::{Arc, RwLock};
@@ -429,7 +429,7 @@ pub fn imap_search(
(_sort_field, _sort_order): (SortField, SortOrder),
folder_hash: FolderHash,
backend: &Arc>>,
-) -> Result> {
+) -> Result> {
let query = query().parse(term)?.1;
let backend_lck = backend.read().unwrap();
diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs
index 1157e03c..69a93e8b 100644
--- a/ui/src/components/mail/listing.rs
+++ b/ui/src/components/mail/listing.rs
@@ -21,6 +21,7 @@
use super::*;
use crate::types::segment_tree::SegmentTree;
+use smallvec::SmallVec;
mod conversations;
pub use self::conversations::*;
@@ -56,10 +57,10 @@ pub trait MailListingTrait: ListingTrait {
a: &ListingAction,
) {
let account = &mut context.accounts[self.coordinates().0];
- let mut envs_to_set: StackVec = StackVec::new();
+ let mut envs_to_set: SmallVec<[EnvelopeHash; 8]> = SmallVec::new();
let folder_hash = account[self.coordinates().1].unwrap().folder.hash();
{
- let mut stack = StackVec::new();
+ let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
stack.push(thread_hash);
while let Some(thread_iter) = stack.pop() {
{
@@ -138,8 +139,8 @@ pub trait MailListingTrait: ListingTrait {
}
}
- fn row_updates(&mut self) -> &mut StackVec;
- fn get_focused_items(&self, _context: &Context) -> StackVec;
+ fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]>;
+ fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]>;
}
pub trait ListingTrait: Component {
diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs
index 0d4df95a..47f81d01 100644
--- a/ui/src/components/mail/listing/compact.rs
+++ b/ui/src/components/mail/listing/compact.rs
@@ -69,18 +69,18 @@ pub struct CompactListing {
/// If `self.view` exists or not.
unfocused: bool,
view: ThreadView,
- row_updates: StackVec,
+ row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option,
id: ComponentId,
}
impl MailListingTrait for CompactListing {
- fn row_updates(&mut self) -> &mut StackVec {
+ fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates
}
- fn get_focused_items(&self, context: &Context) -> StackVec {
+ fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
let cursor_iter;
@@ -96,7 +96,7 @@ impl MailListingTrait for CompactListing {
.flatten()
.chain(cursor_iter.into_iter().flatten())
.cloned();
- StackVec::from_iter(iter.into_iter())
+ SmallVec::from_iter(iter.into_iter())
}
}
@@ -530,7 +530,7 @@ impl CompactListing {
filtered_selection: Vec::new(),
filtered_order: FnvHashMap::default(),
selection: FnvHashMap::default(),
- row_updates: StackVec::new(),
+ row_updates: SmallVec::new(),
data_columns: DataColumns::default(),
dirty: true,
force_draw: true,
@@ -554,7 +554,7 @@ impl CompactListing {
.hash();
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
let mut tags = String::new();
- let mut colors = StackVec::new();
+ let mut colors: SmallVec<[_; 8]> = SmallVec::new();
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
if let Some(t) = backend_lck.tags() {
let tags_lck = t.read().unwrap();
@@ -681,17 +681,17 @@ impl CompactListing {
let mut rows = Vec::with_capacity(1024);
let mut min_width = (0, 0, 0, 0, 0);
let mut row_widths: (
- StackVec,
- StackVec,
- StackVec,
- StackVec,
- StackVec,
+ SmallVec<[u8; 1024]>,
+ SmallVec<[u8; 1024]>,
+ SmallVec<[u8; 1024]>,
+ SmallVec<[u8; 1024]>,
+ SmallVec<[u8; 1024]>,
) = (
- StackVec::new(),
- StackVec::new(),
- StackVec::new(),
- StackVec::new(),
- StackVec::new(),
+ SmallVec::new(),
+ SmallVec::new(),
+ SmallVec::new(),
+ SmallVec::new(),
+ SmallVec::new(),
);
threads.sort_by(self.sort, self.subsort, &account.collection.envelopes);
diff --git a/ui/src/components/mail/listing/conversations.rs b/ui/src/components/mail/listing/conversations.rs
index 3b72cdc4..3b322706 100644
--- a/ui/src/components/mail/listing/conversations.rs
+++ b/ui/src/components/mail/listing/conversations.rs
@@ -73,7 +73,7 @@ column_str!(struct DateString(String));
column_str!(struct FromString(String));
column_str!(struct SubjectString(String));
column_str!(struct FlagString(String));
-column_str!(struct TagString(String, StackVec));
+column_str!(struct TagString(String, SmallVec<[Color; 8]>));
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
/// `ThreadView`.
@@ -100,18 +100,18 @@ pub struct ConversationsListing {
/// If `self.view` exists or not.
unfocused: bool,
view: ThreadView,
- row_updates: StackVec,
+ row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option,
id: ComponentId,
}
impl MailListingTrait for ConversationsListing {
- fn row_updates(&mut self) -> &mut StackVec {
+ fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates
}
- fn get_focused_items(&self, context: &Context) -> StackVec {
+ fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
let cursor_iter;
@@ -127,7 +127,7 @@ impl MailListingTrait for ConversationsListing {
.flatten()
.chain(cursor_iter.into_iter().flatten())
.cloned();
- StackVec::from_iter(iter.into_iter())
+ SmallVec::from_iter(iter.into_iter())
}
}
@@ -500,7 +500,7 @@ impl ConversationsListing {
filtered_selection: Vec::new(),
filtered_order: FnvHashMap::default(),
selection: FnvHashMap::default(),
- row_updates: StackVec::new(),
+ row_updates: SmallVec::new(),
content: Default::default(),
dirty: true,
force_draw: true,
@@ -525,7 +525,7 @@ impl ConversationsListing {
.hash();
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
let mut tags = String::new();
- let mut colors = StackVec::new();
+ let mut colors = SmallVec::new();
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
if let Some(t) = backend_lck.tags() {
let tags_lck = t.read().unwrap();
@@ -690,7 +690,7 @@ impl ConversationsListing {
}
from_address_list.clear();
from_address_set.clear();
- let mut stack = StackVec::new();
+ let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
stack.push(root_idx);
while let Some(h) = stack.pop() {
let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() {
@@ -952,7 +952,7 @@ impl ConversationsListing {
let mut from_address_list = Vec::new();
let mut from_address_set: std::collections::HashSet> =
std::collections::HashSet::new();
- let mut stack = StackVec::new();
+ let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
stack.push(thread_hash);
while let Some(h) = stack.pop() {
let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() {
diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs
index b1f8de8c..c2410416 100644
--- a/ui/src/components/mail/listing/plain.rs
+++ b/ui/src/components/mail/listing/plain.rs
@@ -70,19 +70,19 @@ pub struct PlainListing {
/// If `self.view` exists or not.
unfocused: bool,
view: MailView,
- row_updates: StackVec,
- _row_updates: StackVec,
+ row_updates: SmallVec<[EnvelopeHash; 8]>,
+ _row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option,
id: ComponentId,
}
impl MailListingTrait for PlainListing {
- fn row_updates(&mut self) -> &mut StackVec {
+ fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self._row_updates
}
- fn get_focused_items(&self, context: &Context) -> StackVec {
+ fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
if is_selection_empty {
self.selection
@@ -91,7 +91,7 @@ impl MailListingTrait for PlainListing {
.map(|(k, _)| self.thread_hashes[k])
.collect()
} else {
- let mut ret = StackVec::new();
+ let mut ret = SmallVec::new();
ret.push(self.get_thread_under_cursor(self.cursor_pos.2, context));
ret
}
@@ -484,8 +484,8 @@ impl PlainListing {
filtered_selection: Vec::new(),
filtered_order: FnvHashMap::default(),
selection: FnvHashMap::default(),
- row_updates: StackVec::new(),
- _row_updates: StackVec::new(),
+ row_updates: SmallVec::new(),
+ _row_updates: SmallVec::new(),
data_columns: DataColumns::default(),
dirty: true,
force_draw: true,
@@ -503,7 +503,7 @@ impl PlainListing {
.hash();
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
let mut tags = String::new();
- let mut colors = StackVec::new();
+ let mut colors = SmallVec::new();
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
if let Some(t) = backend_lck.tags() {
let tags_lck = t.read().unwrap();
@@ -1086,7 +1086,7 @@ impl Component for PlainListing {
.flatten()
.chain(cursor_iter.into_iter().flatten())
.cloned();
- let stack = StackVec::from_iter(iter.into_iter());
+ let stack: SmallVec<[_; 8]> = SmallVec::from_iter(iter.into_iter());
for i in stack {
self.perform_action(context, i, a);
}
diff --git a/ui/src/components/mail/listing/thread.rs b/ui/src/components/mail/listing/thread.rs
index eb25a2ec..6a81a735 100644
--- a/ui/src/components/mail/listing/thread.rs
+++ b/ui/src/components/mail/listing/thread.rs
@@ -37,7 +37,7 @@ pub struct ThreadListing {
/// Cache current view.
content: CellBuffer,
- row_updates: StackVec,
+ row_updates: SmallVec<[ThreadHash; 8]>,
locations: Vec,
/// If we must redraw on next redraw event
dirty: bool,
@@ -50,12 +50,12 @@ pub struct ThreadListing {
}
impl MailListingTrait for ThreadListing {
- fn row_updates(&mut self) -> &mut StackVec {
+ fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates
}
- fn get_focused_items(&self, _context: &Context) -> StackVec {
- StackVec::new()
+ fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]> {
+ SmallVec::new()
}
}
@@ -242,7 +242,7 @@ impl ThreadListing {
sort: (Default::default(), Default::default()),
subsort: (Default::default(), Default::default()),
content,
- row_updates: StackVec::new(),
+ row_updates: SmallVec::new(),
locations: Vec::new(),
dirty: true,
unfocused: false,
diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs
index 7fcf78b4..630be357 100644
--- a/ui/src/components/mail/view.rs
+++ b/ui/src/components/mail/view.rs
@@ -22,6 +22,7 @@
use super::*;
use melib::list_management;
use melib::parser::BytesExt;
+use smallvec::SmallVec;
use std::convert::TryFrom;
use std::process::{Command, Stdio};
@@ -229,7 +230,7 @@ impl MailView {
if body.count_attachments() > 1 {
fn attachment_tree(
(idx, (depth, att)): (&mut usize, (usize, &Attachment)),
- branches: &mut StackVec,
+ branches: &mut SmallVec<[bool; 8]>,
has_sibling: bool,
s: &mut String,
) {
@@ -286,7 +287,7 @@ impl MailView {
_ => {}
}
}
- attachment_tree((&mut 0, (0, &body)), &mut StackVec::new(), false, &mut t);
+ attachment_tree((&mut 0, (0, &body)), &mut SmallVec::new(), false, &mut t);
}
t
}
@@ -1385,7 +1386,7 @@ impl Component for MailView {
}
_ => { /* error print message to user */ }
}
- }
+ };
}
UIEvent::Action(Listing(OpenInNewTab)) => {
context
diff --git a/ui/src/components/mail/view/thread.rs b/ui/src/components/mail/view/thread.rs
index 9cdb3110..5964e356 100644
--- a/ui/src/components/mail/view/thread.rs
+++ b/ui/src/components/mail/view/thread.rs
@@ -848,7 +848,7 @@ impl ThreadView {
.iter()
.enumerate()
.fold(
- (vec![Vec::new()], StackVec::new(), false),
+ (vec![Vec::new()], SmallVec::<[_; 8]>::new(), false),
|(mut visies, mut stack, is_prev_hidden), (idx, e)| {
match (e.hidden, is_prev_hidden) {
(true, false) => {
diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs
index 6239cdd5..c4c6ac7c 100644
--- a/ui/src/conf/accounts.rs
+++ b/ui/src/conf/accounts.rs
@@ -34,7 +34,7 @@ use melib::error::{MeliError, Result};
use melib::mailbox::*;
use melib::thread::{SortField, SortOrder, ThreadHash, ThreadNode, Threads};
use melib::AddressBook;
-use melib::StackVec;
+use smallvec::SmallVec;
use text_processing::GlobMatch;
use crate::types::UIEvent::{self, EnvelopeRemove, EnvelopeRename, EnvelopeUpdate, Notification};
@@ -384,7 +384,7 @@ impl Account {
folder_names.insert(f.hash(), f.path().to_string());
}
- let mut stack: StackVec = StackVec::new();
+ let mut stack: SmallVec<[FolderHash; 8]> = SmallVec::new();
let mut tree: Vec = Vec::new();
let mut collection: Collection = Collection::new(Default::default());
for (h, f) in ref_folders.iter() {
@@ -442,7 +442,7 @@ impl Account {
}
});
- let mut stack: StackVec