summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-21 21:23:06 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-21 21:29:33 +0300
commit6e75160b70496d61988fee31d4c28e47f367a518 (patch)
tree6d963625b43c43033efdc0f9b22c551fb6d5a481
parentf066f35410cd631955cff4c5ae1ec49f9826bb36 (diff)
melib: turn unicode algos and backends into features
-rw-r--r--melib/Cargo.toml18
-rw-r--r--melib/src/backends.rs41
-rw-r--r--melib/src/email/compose/mime.rs132
-rw-r--r--melib/src/error.rs2
-rw-r--r--melib/src/lib.rs2
-rw-r--r--melib/src/thread.rs65
6 files changed, 191 insertions, 69 deletions
diff --git a/melib/Cargo.toml b/melib/Cargo.toml
index b76f43d0..441353c2 100644
--- a/melib/Cargo.toml
+++ b/melib/Cargo.toml
@@ -12,16 +12,24 @@ crossbeam = "0.7.2"
data-encoding = "2.1.1"
encoding = "0.2.33"
fnv = "1.0.3"
-memmap = "0.5.2"
+memmap = { version = "0.5.2", optional = true }
nom = "3.2.0"
-notify = "4.0.1"
-notify-rust = "^3"
+notify = { version = "4.0.1", optional = true }
+notify-rust = { version = "^3", optional = true }
termion = "1.5.1"
xdg = "2.1.0"
-native-tls = "0.2"
+native-tls = { version ="0.2", optional=true }
serde = "1.0.71"
serde_derive = "1.0.71"
bincode = "1.0.1"
uuid = { version = "0.6", features = ["serde", "v4"] }
-text_processing = { path = "../text_processing", version = "*" }
+text_processing = { path = "../text_processing", version = "*", optional= true }
libc = {version = "0.2.59", features = ["extra_traits",]}
+
+[features]
+default = ["unicode_algorithms", "imap_backend", "maildir_backend", "mbox_backend"]
+
+unicode_algorithms = ["text_processing"]
+imap_backend = ["native-tls"]
+maildir_backend = ["notify", "notify-rust", "memmap"]
+mbox_backend = ["notify", "notify-rust", "memmap"]
diff --git a/melib/src/backends.rs b/melib/src/backends.rs
index 57cee63a..06bdf251 100644
--- a/melib/src/backends.rs
+++ b/melib/src/backends.rs
@@ -18,16 +18,22 @@
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
+#[cfg(feature = "imap_backend")]
pub mod imap;
+#[cfg(feature = "maildir_backend")]
pub mod maildir;
+#[cfg(feature = "mbox_backend")]
pub mod mbox;
+#[cfg(feature = "imap_backend")]
pub use self::imap::ImapType;
use crate::async_workers::*;
use crate::conf::AccountSettings;
use crate::error::{MeliError, Result};
-//use mailbox::backends::imap::ImapType;
+
+#[cfg(feature = "maildir_backend")]
use self::maildir::MaildirType;
+#[cfg(feature = "mbox_backend")]
use self::mbox::MboxType;
use super::email::{Envelope, EnvelopeHash, Flag};
use std::fmt;
@@ -57,18 +63,27 @@ impl Backends {
let mut b = Backends {
map: FnvHashMap::with_capacity_and_hasher(1, Default::default()),
};
- b.register(
- "maildir".to_string(),
- Box::new(|| Box::new(|f, i| Box::new(MaildirType::new(f, i)))),
- );
- b.register(
- "mbox".to_string(),
- Box::new(|| Box::new(|f, i| Box::new(MboxType::new(f, i)))),
- );
- b.register(
- "imap".to_string(),
- Box::new(|| Box::new(|f, i| Box::new(ImapType::new(f, i)))),
- );
+ #[cfg(feature = "maildir_backend")]
+ {
+ b.register(
+ "maildir".to_string(),
+ Box::new(|| Box::new(|f, i| Box::new(MaildirType::new(f, i)))),
+ );
+ }
+ #[cfg(feature = "mbox_backend")]
+ {
+ b.register(
+ "mbox".to_string(),
+ Box::new(|| Box::new(|f, i| Box::new(MboxType::new(f, i)))),
+ );
+ }
+ #[cfg(feature = "imap_backend")]
+ {
+ b.register(
+ "imap".to_string(),
+ Box::new(|| Box::new(|f, i| Box::new(ImapType::new(f, i)))),
+ );
+ }
b
}
diff --git a/melib/src/email/compose/mime.rs b/melib/src/email/compose/mime.rs
index 081e11d1..371c741b 100644
--- a/melib/src/email/compose/mime.rs
+++ b/melib/src/email/compose/mime.rs
@@ -1,22 +1,51 @@
use super::*;
+
+#[cfg(feature = "unicode_algorithms")]
use text_processing::grapheme_clusters::Graphemes;
pub fn encode_header(value: &str) -> String {
let mut ret = String::with_capacity(value.len());
- let graphemes = value.graphemes_indices();
let mut is_current_window_ascii = true;
let mut current_window_start = 0;
- for (idx, g) in graphemes {
- match (g.is_ascii(), is_current_window_ascii) {
- (true, true) => {
- ret.push_str(g);
- }
- (true, false) => {
- /* If !g.is_whitespace()
- *
- * Whitespaces inside encoded tokens must be greedily taken,
- * instead of splitting each non-ascii word into separate encoded tokens. */
- if !g.split_whitespace().collect::<Vec<&str>>().is_empty() {
+ #[cfg(feature = "unicode_algorithms")]
+ {
+ let graphemes = value.graphemes_indices();
+ for (idx, g) in graphemes {
+ match (g.is_ascii(), is_current_window_ascii) {
+ (true, true) => {
+ ret.push_str(g);
+ }
+ (true, false) => {
+ /* If !g.is_whitespace()
+ *
+ * Whitespaces inside encoded tokens must be greedily taken,
+ * instead of splitting each non-ascii word into separate encoded tokens. */
+ if !g.split_whitespace().collect::<Vec<&str>>().is_empty() {
+ ret.push_str(&format!(
+ "=?UTF-8?B?{}?=",
+ BASE64_MIME
+ .encode(value[current_window_start..idx].as_bytes())
+ .trim()
+ ));
+ if idx != value.len() - 1 {
+ ret.push(' ');
+ }
+ is_current_window_ascii = true;
+ current_window_start = idx;
+ ret.push_str(g);
+ }
+ }
+ (false, true) => {
+ current_window_start = idx;
+ is_current_window_ascii = false;
+ }
+ /* RFC2047 recommends:
+ * 'While there is no limit to the length of a multiple-line header field, each line of
+ * a header field that contains one or more 'encoded-word's is limited to 76
+ * characters.'
+ * This is a rough compliance.
+ */
+ (false, false) if (((4 * (idx - current_window_start) / 3) + 3) & !3) > 33 => {
ret.push_str(&format!(
"=?UTF-8?B?{}?=",
BASE64_MIME
@@ -26,34 +55,67 @@ pub fn encode_header(value: &str) -> String {
if idx != value.len() - 1 {
ret.push(' ');
}
- is_current_window_ascii = true;
current_window_start = idx;
- ret.push_str(g);
}
+ (false, false) => {}
}
- (false, true) => {
- current_window_start = idx;
- is_current_window_ascii = false;
- }
- /* RFC2047 recommends:
- * 'While there is no limit to the length of a multiple-line header field, each line of
- * a header field that contains one or more 'encoded-word's is limited to 76
- * characters.'
- * This is a rough compliance.
- */
- (false, false) if (((4 * (idx - current_window_start) / 3) + 3) & !3) > 33 => {
- ret.push_str(&format!(
- "=?UTF-8?B?{}?=",
- BASE64_MIME
- .encode(value[current_window_start..idx].as_bytes())
- .trim()
- ));
- if idx != value.len() - 1 {
- ret.push(' ');
+ }
+ }
+ #[cfg(not(feature = "unicode_algorithms"))]
+ {
+ /* TODO: test this. If it works as fine as the one above, there's no need to keep the above
+ * implementation.*/
+ let mut idx = 0;
+ for g in value.chars() {
+ match (g.is_ascii(), is_current_window_ascii) {
+ (true, true) => {
+ ret.push(g);
+ }
+ (true, false) => {
+ /* If !g.is_whitespace()
+ *
+ * Whitespaces inside encoded tokens must be greedily taken,
+ * instead of splitting each non-ascii word into separate encoded tokens. */
+ if !g.is_whitespace() {
+ ret.push_str(&format!(
+ "=?UTF-8?B?{}?=",
+ BASE64_MIME
+ .encode(value[current_window_start..idx].as_bytes())
+ .trim()
+ ));
+ if idx != value.len() - 1 {
+ ret.push(' ');
+ }
+ is_current_window_ascii = true;
+ current_window_start = idx;
+ ret.push(g);
+ }
+ }
+ (false, true) => {
+ current_window_start = idx;
+ is_current_window_ascii = false;
+ }
+ /* RFC2047 recommends:
+ * 'While there is no limit to the length of a multiple-line header field, each line of
+ * a header field that contains one or more 'encoded-word's is limited to 76
+ * characters.'
+ * This is a rough compliance.
+ */
+ (false, false) if (((4 * (idx - current_window_start) / 3) + 3) & !3) > 33 => {
+ ret.push_str(&format!(
+ "=?UTF-8?B?{}?=",
+ BASE64_MIME
+ .encode(value[current_window_start..idx].as_bytes())
+ .trim()
+ ));
+ if idx != value.len() - 1 {
+ ret.push(' ');
+ }
+ current_window_start = idx;
}
- current_window_start = idx;
+ (false, false) => {}
}
- (false, false) => {}
+ idx += std::mem::size_of::<char>();
}
}
/* If the last part of the header value is encoded, it won't be pushed inside the previous for
diff --git a/melib/src/error.rs b/melib/src/error.rs
index 7d8c0813..3f5ffdca 100644
--- a/melib/src/error.rs
+++ b/melib/src/error.rs
@@ -118,6 +118,7 @@ impl<T> From<std::sync::PoisonError<T>> for MeliError {
}
}
+#[cfg(feature = "imap_backend")]
impl From<native_tls::HandshakeError<std::net::TcpStream>> for MeliError {
#[inline]
fn from(kind: native_tls::HandshakeError<std::net::TcpStream>) -> MeliError {
@@ -125,6 +126,7 @@ impl From<native_tls::HandshakeError<std::net::TcpStream>> for MeliError {
}
}
+#[cfg(feature = "imap_backend")]
impl From<native_tls::Error> for MeliError {
#[inline]
fn from(kind: native_tls::Error) -> MeliError {
diff --git a/melib/src/lib.rs b/melib/src/lib.rs
index a43f90ed..c908aec9 100644
--- a/melib/src/lib.rs
+++ b/melib/src/lib.rs
@@ -84,6 +84,7 @@ pub mod dbg {
}
}
+#[cfg(feature = "unicode_algorithms")]
extern crate text_processing;
#[macro_use]
@@ -113,7 +114,6 @@ extern crate nom;
extern crate chrono;
extern crate data_encoding;
extern crate encoding;
-extern crate memmap;
#[macro_use]
extern crate bitflags;
diff --git a/melib/src/thread.rs b/melib/src/thread.rs
index 0daa2ddf..89981b5b 100644
--- a/melib/src/thread.rs
+++ b/melib/src/thread.rs
@@ -35,6 +35,8 @@
use crate::email::parser::BytesExt;
use crate::email::*;
use crate::structs::StackVec;
+
+#[cfg(feature = "unicode_algorithms")]
use text_processing::grapheme_clusters::*;
use uuid::Uuid;
@@ -504,10 +506,19 @@ impl ThreadNode {
buf.get(&probe).map(|n| n.message.as_ref()).unwrap_or(None),
buf.get(&child).map(|n| n.message.as_ref()).unwrap_or(None),
) {
- (Some(p), Some(c)) => envelopes[p]
- .subject()
- .split_graphemes()
- .cmp(&envelopes[c].subject().split_graphemes()),
+ (Some(p), Some(c)) => {
+ #[cfg(feature = "unicode_algorithms")]
+ {
+ envelopes[p]
+ .subject()
+ .split_graphemes()
+ .cmp(&envelopes[c].subject().split_graphemes())
+ }
+ #[cfg(not(feature = "unicode_algorithms"))]
+ {
+ envelopes[p].subject().cmp(&envelopes[c].subject())
+ }
+ }
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
(None, None) => Ordering::Equal,
@@ -523,10 +534,19 @@ impl ThreadNode {
buf.get(&probe).map(|n| n.message.as_ref()).unwrap_or(None),
buf.get(&child).map(|n| n.message.as_ref()).unwrap_or(None),
) {
- (Some(p), Some(c)) => envelopes[c]
- .subject()
- .split_graphemes()
- .cmp(&envelopes[p].subject().split_graphemes()),
+ (Some(p), Some(c)) => {
+ #[cfg(feature = "unicode_algorithms")]
+ {
+ envelopes[c]
+ .subject()
+ .split_graphemes()
+ .cmp(&envelopes[p].subject().split_graphemes())
+ }
+ #[cfg(not(feature = "unicode_algorithms"))]
+ {
+ envelopes[c].subject().cmp(&envelopes[p].subject())
+ }
+ }
(Some(_), None) => Ordering::Less,
(None, Some(_)) => Ordering::Greater,
(None, None) => Ordering::Equal,
@@ -1078,9 +1098,16 @@ impl Threads {
}
let ma = &envelopes[&a.unwrap()];
let mb = &envelopes[&b.unwrap()];
- ma.subject()
- .split_graphemes()
- .cmp(&mb.subject().split_graphemes())
+ #[cfg(feature = "unicode_algorithms")]
+ {
+ ma.subject()
+ .split_graphemes()
+ .cmp(&mb.subject().split_graphemes())
+ }
+ #[cfg(not(feature = "unicode_algorithms"))]
+ {
+ ma.subject().cmp(&mb.subject())
+ }
}
(SortField::Subject, SortOrder::Asc) => {
let a = &self.thread_nodes[&a].message();
@@ -1100,10 +1127,18 @@ impl Threads {
}
let ma = &envelopes[&a.unwrap()];
let mb = &envelopes[&b.unwrap()];
- mb.subject()
- .as_ref()
- .split_graphemes()
- .cmp(&ma.subject().split_graphemes())
+ #[cfg(feature = "unicode_algorithms")]
+ {
+ mb.subject()
+ .as_ref()
+ .split_graphemes()
+ .cmp(&ma.subject().split_graphemes())
+ }
+
+ #[cfg(not(feature = "unicode_algorithms"))]
+ {
+ mb.subject().as_ref().cmp(&ma.subject())
+ }
}
});
}