Fix some clippy suggestions

master
Manos Pitsidianakis 2021-09-12 14:33:00 +03:00
parent 592339bdca
commit 733de5a5fb
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
17 changed files with 108 additions and 131 deletions

View File

@ -163,7 +163,7 @@ fn main() -> Result<(), std::io::Error> {
fn set_general_categories<'u>(codepoints: &mut Vec<Codepoint<'u>>, unicode_data: &'u str) { fn set_general_categories<'u>(codepoints: &mut Vec<Codepoint<'u>>, unicode_data: &'u str) {
for line in unicode_data.lines() { for line in unicode_data.lines() {
let fields = line.trim().split(";").collect::<Vec<_>>(); let fields = line.trim().split(';').collect::<Vec<_>>();
if fields.len() > FIELD_CATEGORY { if fields.len() > FIELD_CATEGORY {
for idx in hexrange_to_range(fields[FIELD_CODEPOINT]) { for idx in hexrange_to_range(fields[FIELD_CODEPOINT]) {
codepoints[idx].category = fields[FIELD_CATEGORY]; codepoints[idx].category = fields[FIELD_CATEGORY];
@ -223,7 +223,7 @@ fn main() -> Result<(), std::io::Error> {
fn set_emoji_widths(codepoints: &mut Vec<Codepoint<'_>>, emoji_data_lines: &str) { fn set_emoji_widths(codepoints: &mut Vec<Codepoint<'_>>, emoji_data_lines: &str) {
// Read from emoji-data.txt, set codepoint widths // Read from emoji-data.txt, set codepoint widths
for line in emoji_data_lines.lines() { for line in emoji_data_lines.lines() {
if !line.contains("#") || line.trim().starts_with("#") { if !line.contains('#') || line.trim().starts_with('#') {
continue; continue;
} }
let mut fields = line.trim().split('#').collect::<Vec<_>>(); let mut fields = line.trim().split('#').collect::<Vec<_>>();
@ -233,7 +233,7 @@ fn main() -> Result<(), std::io::Error> {
let comment = fields.pop().unwrap(); let comment = fields.pop().unwrap();
let fields = fields.pop().unwrap(); let fields = fields.pop().unwrap();
let hexrange = fields.split(";").next().unwrap(); let hexrange = fields.split(';').next().unwrap();
// In later versions of emoji-data.txt there are some "reserved" // In later versions of emoji-data.txt there are some "reserved"
// entries that have "NA" instead of a Unicode version number // entries that have "NA" instead of a Unicode version number
@ -245,7 +245,7 @@ fn main() -> Result<(), std::io::Error> {
use std::str::FromStr; use std::str::FromStr;
let mut v = comment.trim().split_whitespace().next().unwrap(); let mut v = comment.trim().split_whitespace().next().unwrap();
if v.starts_with("E") { if v.starts_with('E') {
v = &v[1..]; v = &v[1..];
} }
if v.as_bytes() if v.as_bytes()

View File

@ -105,7 +105,7 @@ impl AddressBook {
{ {
let mut ret = AddressBook::new(s.name.clone()); let mut ret = AddressBook::new(s.name.clone());
if let Some(vcard_path) = s.vcard_folder() { if let Some(vcard_path) = s.vcard_folder() {
if let Ok(cards) = vcard::load_cards(&std::path::Path::new(vcard_path)) { if let Ok(cards) = vcard::load_cards(std::path::Path::new(vcard_path)) {
for c in cards { for c in cards {
ret.add_card(c); ret.add_card(c);
} }

View File

@ -274,10 +274,10 @@ pub fn load_cards(p: &std::path::Path) -> Result<Vec<Card>> {
ret.push( ret.push(
CardDeserializer::from_str(s) CardDeserializer::from_str(s)
.and_then(TryInto::try_into) .and_then(TryInto::try_into)
.and_then(|mut card| { .map(|mut card| {
Card::set_external_resource(&mut card, true); Card::set_external_resource(&mut card, true);
is_any_valid = true; is_any_valid = true;
Ok(card) card
}), }),
); );
} }
@ -290,12 +290,10 @@ pub fn load_cards(p: &std::path::Path) -> Result<Vec<Card>> {
debug!(&c); debug!(&c);
} }
} }
if !is_any_valid { if is_any_valid {
ret.into_iter().collect::<Result<Vec<Card>>>()
} else {
ret.retain(Result::is_ok); ret.retain(Result::is_ok);
ret.into_iter().collect::<Result<Vec<Card>>>()
} }
ret.into_iter().collect::<Result<Vec<Card>>>()
} }
#[test] #[test]

View File

@ -1178,20 +1178,20 @@ impl MailBackend for ImapType {
keyword => { keyword => {
s.push_str(" KEYWORD "); s.push_str(" KEYWORD ");
s.push_str(keyword); s.push_str(keyword);
s.push_str(" "); s.push(' ');
} }
} }
} }
} }
And(q1, q2) => { And(q1, q2) => {
rec(q1, s); rec(q1, s);
s.push_str(" "); s.push(' ');
rec(q2, s); rec(q2, s);
} }
Or(q1, q2) => { Or(q1, q2) => {
s.push_str(" OR "); s.push_str(" OR ");
rec(q1, s); rec(q1, s);
s.push_str(" "); s.push(' ');
rec(q2, s); rec(q2, s);
} }
Not(q) => { Not(q) => {
@ -1433,7 +1433,7 @@ impl ImapType {
if !l.starts_with(b"*") { if !l.starts_with(b"*") {
continue; continue;
} }
if let Ok(mut mailbox) = protocol_parser::list_mailbox_result(&l).map(|(_, v)| v) { if let Ok(mut mailbox) = protocol_parser::list_mailbox_result(l).map(|(_, v)| v) {
if let Some(parent) = mailbox.parent { if let Some(parent) = mailbox.parent {
if mailboxes.contains_key(&parent) { if mailboxes.contains_key(&parent) {
mailboxes mailboxes
@ -1785,7 +1785,7 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result<Vec<Envelope>> {
ref uid, ref uid,
ref mut envelope, ref mut envelope,
ref mut flags, ref mut flags,
ref raw_fetch_value, raw_fetch_value,
ref references, ref references,
.. ..
} in v.iter_mut() } in v.iter_mut()

View File

@ -319,7 +319,7 @@ impl ImapStream {
.find(|l| l.starts_with(b"* CAPABILITY")) .find(|l| l.starts_with(b"* CAPABILITY"))
.ok_or_else(|| MeliError::new("")) .ok_or_else(|| MeliError::new(""))
.and_then(|res| { .and_then(|res| {
protocol_parser::capabilities(&res) protocol_parser::capabilities(res)
.map_err(|_| MeliError::new("")) .map_err(|_| MeliError::new(""))
.map(|(_, v)| v) .map(|(_, v)| v)
}); });
@ -392,7 +392,7 @@ impl ImapStream {
let mut should_break = false; let mut should_break = false;
for l in res.split_rn() { for l in res.split_rn() {
if l.starts_with(b"* CAPABILITY") { if l.starts_with(b"* CAPABILITY") {
capabilities = protocol_parser::capabilities(&l) capabilities = protocol_parser::capabilities(l)
.map(|(_, capabilities)| { .map(|(_, capabilities)| {
HashSet::from_iter(capabilities.into_iter().map(|s: &[u8]| s.to_vec())) HashSet::from_iter(capabilities.into_iter().map(|s: &[u8]| s.to_vec()))
}) })
@ -875,9 +875,9 @@ impl ImapConnection {
debug!( debug!(
"{} select response {}", "{} select response {}",
imap_path, imap_path,
String::from_utf8_lossy(&ret) String::from_utf8_lossy(ret)
); );
let select_response = protocol_parser::select_response(&ret).chain_err_summary(|| { let select_response = protocol_parser::select_response(ret).chain_err_summary(|| {
format!("Could not parse select response for mailbox {}", imap_path) format!("Could not parse select response for mailbox {}", imap_path)
})?; })?;
{ {
@ -958,8 +958,8 @@ impl ImapConnection {
.await?; .await?;
self.read_response(ret, RequiredResponses::EXAMINE_REQUIRED) self.read_response(ret, RequiredResponses::EXAMINE_REQUIRED)
.await?; .await?;
debug!("examine response {}", String::from_utf8_lossy(&ret)); debug!("examine response {}", String::from_utf8_lossy(ret));
let select_response = protocol_parser::select_response(&ret).chain_err_summary(|| { let select_response = protocol_parser::select_response(ret).chain_err_summary(|| {
format!("Could not parse select response for mailbox {}", imap_path) format!("Could not parse select response for mailbox {}", imap_path)
})?; })?;
self.stream.as_mut()?.current_mailbox = MailboxSelection::Examine(mailbox_hash); self.stream.as_mut()?.current_mailbox = MailboxSelection::Examine(mailbox_hash);

View File

@ -154,7 +154,7 @@ impl BackendOp for ImapOp {
.set_summary(format!("message with UID {} was not found?", uid))); .set_summary(format!("message with UID {} was not found?", uid)));
} }
let (_uid, (_flags, _)) = v[0]; let (_uid, (_flags, _)) = v[0];
assert_eq!(uid, uid); assert_eq!(_uid, uid);
let mut bytes_cache = uid_store.byte_cache.lock()?; let mut bytes_cache = uid_store.byte_cache.lock()?;
let cache = bytes_cache.entry(uid).or_default(); let cache = bytes_cache.entry(uid).or_default();
cache.flags = Some(_flags); cache.flags = Some(_flags);

View File

@ -119,8 +119,8 @@ impl RequiredResponses {
} }
if self.intersects(RequiredResponses::FETCH) { if self.intersects(RequiredResponses::FETCH) {
let mut ptr = 0; let mut ptr = 0;
for i in 0..line.len() { for (i, l) in line.iter().enumerate() {
if !line[i].is_ascii_digit() { if !l.is_ascii_digit() {
ptr = i; ptr = i;
break; break;
} }
@ -257,7 +257,7 @@ pub enum ImapResponse {
impl TryFrom<&'_ [u8]> for ImapResponse { impl TryFrom<&'_ [u8]> for ImapResponse {
type Error = MeliError; type Error = MeliError;
fn try_from(val: &'_ [u8]) -> Result<ImapResponse> { fn try_from(val: &'_ [u8]) -> Result<ImapResponse> {
let val: &[u8] = val.split_rn().last().unwrap_or(val.as_ref()); let val: &[u8] = val.split_rn().last().unwrap_or_else(|| val.as_ref());
let mut val = val[val.find(b" ").ok_or_else(|| { let mut val = val[val.find(b" ").ok_or_else(|| {
MeliError::new(format!( MeliError::new(format!(
"Expected tagged IMAP response (OK,NO,BAD, etc) but found {:?}", "Expected tagged IMAP response (OK,NO,BAD, etc) but found {:?}",
@ -594,7 +594,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
} else { } else {
return debug!(Err(MeliError::new(format!( return debug!(Err(MeliError::new(format!(
"Unexpected input while parsing UID FETCH response. Got: `{:.40}`", "Unexpected input while parsing UID FETCH response. Got: `{:.40}`",
String::from_utf8_lossy(&input) String::from_utf8_lossy(input)
)))); ))));
} }
} else if input[i..].starts_with(b"FLAGS (") { } else if input[i..].starts_with(b"FLAGS (") {
@ -605,7 +605,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
} else { } else {
return debug!(Err(MeliError::new(format!( return debug!(Err(MeliError::new(format!(
"Unexpected input while parsing UID FETCH response. Got: `{:.40}`", "Unexpected input while parsing UID FETCH response. Got: `{:.40}`",
String::from_utf8_lossy(&input) String::from_utf8_lossy(input)
)))); ))));
} }
} else if input[i..].starts_with(b"MODSEQ (") { } else if input[i..].starts_with(b"MODSEQ (") {
@ -621,7 +621,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
} else { } else {
return debug!(Err(MeliError::new(format!( return debug!(Err(MeliError::new(format!(
"Unexpected input while parsing MODSEQ in UID FETCH response. Got: `{:.40}`", "Unexpected input while parsing MODSEQ in UID FETCH response. Got: `{:.40}`",
String::from_utf8_lossy(&input) String::from_utf8_lossy(input)
)))); ))));
} }
} else if input[i..].starts_with(b"RFC822 {") { } else if input[i..].starts_with(b"RFC822 {") {
@ -640,7 +640,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
} else { } else {
return debug!(Err(MeliError::new(format!( return debug!(Err(MeliError::new(format!(
"Unexpected input while parsing UID FETCH response. Got: `{:.40}`", "Unexpected input while parsing UID FETCH response. Got: `{:.40}`",
String::from_utf8_lossy(&input) String::from_utf8_lossy(input)
)))); ))));
} }
} else if input[i..].starts_with(b"ENVELOPE (") { } else if input[i..].starts_with(b"ENVELOPE (") {
@ -682,7 +682,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
} else { } else {
debug!( debug!(
"Got unexpected token while parsing UID FETCH response:\n`{}`\n", "Got unexpected token while parsing UID FETCH response:\n`{}`\n",
String::from_utf8_lossy(&input) String::from_utf8_lossy(input)
); );
return debug!(Err(MeliError::new(format!( return debug!(Err(MeliError::new(format!(
"Got unexpected token while parsing UID FETCH response: `{:.40}`", "Got unexpected token while parsing UID FETCH response: `{:.40}`",
@ -893,7 +893,7 @@ pub fn untagged_responses(input: &[u8]) -> ImapParseResult<Option<UntaggedRespon
let (input, _) = tag::<_, &[u8], (&[u8], nom::error::ErrorKind)>(b"\r\n")(input)?; let (input, _) = tag::<_, &[u8], (&[u8], nom::error::ErrorKind)>(b"\r\n")(input)?;
debug!( debug!(
"Parse untagged response from {:?}", "Parse untagged response from {:?}",
String::from_utf8_lossy(&orig_input) String::from_utf8_lossy(orig_input)
); );
Ok(( Ok((
input, input,
@ -1091,7 +1091,7 @@ pub fn select_response(input: &[u8]) -> Result<SelectResponse> {
let (_, highestmodseq) = res?; let (_, highestmodseq) = res?;
ret.highestmodseq = Some( ret.highestmodseq = Some(
std::num::NonZeroU64::new(u64::from_str(&String::from_utf8_lossy( std::num::NonZeroU64::new(u64::from_str(&String::from_utf8_lossy(
&highestmodseq, highestmodseq,
))?) ))?)
.map(|u| Ok(ModSequence(u))) .map(|u| Ok(ModSequence(u)))
.unwrap_or(Err(())), .unwrap_or(Err(())),
@ -1099,12 +1099,12 @@ pub fn select_response(input: &[u8]) -> Result<SelectResponse> {
} else if l.starts_with(b"* OK [NOMODSEQ") { } else if l.starts_with(b"* OK [NOMODSEQ") {
ret.highestmodseq = Some(Err(())); ret.highestmodseq = Some(Err(()));
} else if !l.is_empty() { } else if !l.is_empty() {
debug!("select response: {}", String::from_utf8_lossy(&l)); debug!("select response: {}", String::from_utf8_lossy(l));
} }
} }
Ok(ret) Ok(ret)
} else { } else {
let ret = String::from_utf8_lossy(&input).to_string(); let ret = String::from_utf8_lossy(input).to_string();
debug!("BAD/NO response in select: {}", &ret); debug!("BAD/NO response in select: {}", &ret);
Err(MeliError::new(ret)) Err(MeliError::new(ret))
} }
@ -1215,7 +1215,7 @@ pub fn flags(input: &[u8]) -> IResult<&[u8], (Flag, Vec<String>)> {
} }
(true, t) if t.eq_ignore_ascii_case(b"Recent") => { /* ignore */ } (true, t) if t.eq_ignore_ascii_case(b"Recent") => { /* ignore */ }
(_, f) => { (_, f) => {
keywords.push(String::from_utf8_lossy(&f).into()); keywords.push(String::from_utf8_lossy(f).into());
} }
} }
input = &input[match_end..]; input = &input[match_end..];
@ -1385,7 +1385,7 @@ pub fn envelope_address(input: &[u8]) -> IResult<&[u8], Address> {
to_str!(&name), to_str!(&name),
if name.is_empty() { "" } else { " " }, if name.is_empty() { "" } else { " " },
to_str!(&mailbox_name), to_str!(&mailbox_name),
to_str!(&host_name) to_str!(host_name)
) )
.into_bytes() .into_bytes()
} else { } else {
@ -1453,7 +1453,7 @@ pub fn quoted(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
} }
pub fn quoted_or_nil(input: &[u8]) -> IResult<&[u8], Option<Vec<u8>>> { pub fn quoted_or_nil(input: &[u8]) -> IResult<&[u8], Option<Vec<u8>>> {
alt((map(tag("NIL"), |_| None), map(quoted, |v| Some(v))))(input.ltrim()) alt((map(tag("NIL"), |_| None), map(quoted, Some)))(input.ltrim())
} }
pub fn uid_fetch_envelopes_response( pub fn uid_fetch_envelopes_response(
@ -1526,7 +1526,7 @@ fn eat_whitespace(mut input: &[u8]) -> IResult<&[u8], ()> {
break; break;
} }
} }
return Ok((input, ())); Ok((input, ()))
} }
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]

View File

@ -276,7 +276,7 @@ pub async fn examine_updates(
if !l.starts_with(b"*") { if !l.starts_with(b"*") {
continue; continue;
} }
if let Ok(status) = protocol_parser::status_response(&l).map(|(_, v)| v) { if let Ok(status) = protocol_parser::status_response(l).map(|(_, v)| v) {
if Some(mailbox_hash) == status.mailbox { if Some(mailbox_hash) == status.mailbox {
if let Some(total) = status.messages { if let Some(total) = status.messages {
if let Ok(mut exists_lck) = mailbox.exists.lock() { if let Ok(mut exists_lck) = mailbox.exists.lock() {
@ -326,10 +326,8 @@ pub async fn examine_updates(
return Ok(()); return Ok(());
} }
let mut cmd = "UID FETCH ".to_string(); let mut cmd = "UID FETCH ".to_string();
if v.len() == 1 { cmd.push_str(&v[0].to_string());
cmd.push_str(&v[0].to_string()); if v.len() != 1 {
} else {
cmd.push_str(&v[0].to_string());
for n in v.into_iter().skip(1) { for n in v.into_iter().skip(1) {
cmd.push(','); cmd.push(',');
cmd.push_str(&n.to_string()); cmd.push_str(&n.to_string());
@ -372,7 +370,7 @@ pub async fn examine_updates(
{ {
let uid = uid.unwrap(); let uid = uid.unwrap();
let env = envelope.as_mut().unwrap(); let env = envelope.as_mut().unwrap();
env.set_hash(generate_envelope_hash(&mailbox.imap_path(), &uid)); env.set_hash(generate_envelope_hash(mailbox.imap_path(), &uid));
if let Some(value) = references { if let Some(value) = references {
env.set_references(value); env.set_references(value);
} }
@ -392,17 +390,15 @@ pub async fn examine_updates(
} }
} }
} }
if uid_store.keep_offline_cache { if uid_store.keep_offline_cache && cache_handle.mailbox_state(mailbox_hash)?.is_some() {
if !cache_handle.mailbox_state(mailbox_hash)?.is_none() { cache_handle
cache_handle .insert_envelopes(mailbox_hash, &v)
.insert_envelopes(mailbox_hash, &v) .chain_err_summary(|| {
.chain_err_summary(|| { format!(
format!( "Could not save envelopes in cache for mailbox {}",
"Could not save envelopes in cache for mailbox {}", mailbox.imap_path()
mailbox.imap_path() )
) })?;
})?;
}
} }
for FetchResponse { uid, envelope, .. } in v { for FetchResponse { uid, envelope, .. } in v {

View File

@ -295,7 +295,7 @@ impl MailBackend for NntpType {
let mut hash_index_lck = uid_store.hash_index.lock().unwrap(); let mut hash_index_lck = uid_store.hash_index.lock().unwrap();
let mut uid_index_lck = uid_store.uid_index.lock().unwrap(); let mut uid_index_lck = uid_store.uid_index.lock().unwrap();
for l in res.split_rn().skip(1) { for l in res.split_rn().skip(1) {
let (_, (num, env)) = protocol_parser::over_article(&l)?; let (_, (num, env)) = protocol_parser::over_article(l)?;
env_hash_set.insert(env.hash()); env_hash_set.insert(env.hash());
message_id_lck.insert(env.message_id_display().to_string(), env.hash()); message_id_lck.insert(env.message_id_display().to_string(), env.hash());
hash_index_lck.insert(env.hash(), (num, mailbox_hash)); hash_index_lck.insert(env.hash(), (num, mailbox_hash));
@ -736,7 +736,7 @@ impl NntpType {
.lock() .lock()
.unwrap() .unwrap()
.iter() .iter()
.map(|c| c.clone()) .cloned()
.collect::<Vec<String>>() .collect::<Vec<String>>()
} }
} }
@ -778,9 +778,9 @@ impl FetchState {
&uid_store.account_name, path, res &uid_store.account_name, path, res
))); )));
} }
let total = usize::from_str(&s[1]).unwrap_or(0); let total = usize::from_str(s[1]).unwrap_or(0);
let _low = usize::from_str(&s[2]).unwrap_or(0); let _low = usize::from_str(s[2]).unwrap_or(0);
let high = usize::from_str(&s[3]).unwrap_or(0); let high = usize::from_str(s[3]).unwrap_or(0);
*high_low_total = Some((high, _low, total)); *high_low_total = Some((high, _low, total));
{ {
let f = &uid_store.mailboxes.lock().await[&mailbox_hash]; let f = &uid_store.mailboxes.lock().await[&mailbox_hash];
@ -816,7 +816,7 @@ impl FetchState {
let mut hash_index_lck = uid_store.hash_index.lock().unwrap(); let mut hash_index_lck = uid_store.hash_index.lock().unwrap();
let mut uid_index_lck = uid_store.uid_index.lock().unwrap(); let mut uid_index_lck = uid_store.uid_index.lock().unwrap();
for l in res.split_rn().skip(1) { for l in res.split_rn().skip(1) {
let (_, (num, env)) = protocol_parser::over_article(&l)?; let (_, (num, env)) = protocol_parser::over_article(l)?;
message_id_lck.insert(env.message_id_display().to_string(), env.hash()); message_id_lck.insert(env.message_id_display().to_string(), env.hash());
hash_index_lck.insert(env.hash(), (num, mailbox_hash)); hash_index_lck.insert(env.hash(), (num, mailbox_hash));
uid_index_lck.insert((mailbox_hash, num), env.hash()); uid_index_lck.insert((mailbox_hash, num), env.hash());

View File

@ -1055,18 +1055,18 @@ impl MelibQueryToNotmuchQuery for crate::search::Query {
ret.push_str("tag:attachment"); ret.push_str("tag:attachment");
} }
And(q1, q2) => { And(q1, q2) => {
ret.push_str("("); ret.push('(');
q1.query_to_string(ret); q1.query_to_string(ret);
ret.push_str(") AND ("); ret.push_str(") AND (");
q2.query_to_string(ret); q2.query_to_string(ret);
ret.push_str(")"); ret.push(')');
} }
Or(q1, q2) => { Or(q1, q2) => {
ret.push_str("("); ret.push('(');
q1.query_to_string(ret); q1.query_to_string(ret);
ret.push_str(") OR ("); ret.push_str(") OR (");
q2.query_to_string(ret); q2.query_to_string(ret);
ret.push_str(")"); ret.push(')');
} }
Not(q) => { Not(q) => {
ret.push_str("(NOT ("); ret.push_str("(NOT (");

View File

@ -134,10 +134,7 @@ impl Locale {
if new_locale.is_null() { if new_locale.is_null() {
return Err(nix::Error::last().into()); return Err(nix::Error::last().into());
} }
Ok(Locale { Ok(Locale { mask, old_locale })
mask,
old_locale,
})
} }
} }
@ -196,7 +193,7 @@ fn tm_to_secs(tm: libc::tm) -> std::result::Result<i64, ()> {
let mut is_leap = false; let mut is_leap = false;
let mut year = tm.tm_year; let mut year = tm.tm_year;
let mut month = tm.tm_mon; let mut month = tm.tm_mon;
if month >= 12 || month < 0 { if !(0..12).contains(&month) {
let mut adj = month / 12; let mut adj = month / 12;
month %= 12; month %= 12;
if month < 0 { if month < 0 {
@ -229,9 +226,7 @@ fn year_to_secs(year: i64, is_leap: &mut bool) -> std::result::Result<i64, ()> {
} else { } else {
*is_leap = false; *is_leap = false;
} }
return Ok((31536000 * (y - 70) + 86400 * leaps) return Ok(31536000 * (y - 70) + 86400 * leaps);
.try_into()
.unwrap_or(0));
} }
let cycles = (year - 100) / 400; let cycles = (year - 100) / 400;

View File

@ -804,7 +804,7 @@ pub fn interpret_format_flowed(_t: &str) -> String {
unimplemented!() unimplemented!()
} }
type Filter<'a> = Box<dyn FnMut(&Attachment, &mut Vec<u8>) -> () + 'a>; type Filter<'a> = Box<dyn FnMut(&Attachment, &mut Vec<u8>) + 'a>;
fn decode_rec_helper<'a, 'b>(a: &'a Attachment, filter: &mut Option<Filter<'b>>) -> Vec<u8> { fn decode_rec_helper<'a, 'b>(a: &'a Attachment, filter: &mut Option<Filter<'b>>) -> Vec<u8> {
match a.content_type { match a.content_type {

View File

@ -144,22 +144,6 @@ impl Draft {
if let Some(reply_to) = envelope.other_headers().get("Mail-Followup-To") { if let Some(reply_to) = envelope.other_headers().get("Mail-Followup-To") {
ret.headers_mut() ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string()); .insert(HeaderName::new_unchecked("To"), reply_to.to_string());
} else {
if let Some(reply_to) = envelope.other_headers().get("Reply-To") {
ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string());
} else {
ret.headers_mut().insert(
HeaderName::new_unchecked("To"),
envelope.field_from_to_string(),
);
}
// FIXME: add To/Cc
}
} else {
if let Some(reply_to) = envelope.other_headers().get("Mail-Reply-To") {
ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string());
} else if let Some(reply_to) = envelope.other_headers().get("Reply-To") { } else if let Some(reply_to) = envelope.other_headers().get("Reply-To") {
ret.headers_mut() ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string()); .insert(HeaderName::new_unchecked("To"), reply_to.to_string());
@ -169,6 +153,18 @@ impl Draft {
envelope.field_from_to_string(), envelope.field_from_to_string(),
); );
} }
// FIXME: add To/Cc
} else if let Some(reply_to) = envelope.other_headers().get("Mail-Reply-To") {
ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string());
} else if let Some(reply_to) = envelope.other_headers().get("Reply-To") {
ret.headers_mut()
.insert(HeaderName::new_unchecked("To"), reply_to.to_string());
} else {
ret.headers_mut().insert(
HeaderName::new_unchecked("To"),
envelope.field_from_to_string(),
);
} }
ret.headers_mut().insert( ret.headers_mut().insert(
HeaderName::new_unchecked("Cc"), HeaderName::new_unchecked("Cc"),

View File

@ -35,11 +35,11 @@ extern crate unicode_segmentation;
use self::unicode_segmentation::UnicodeSegmentation; use self::unicode_segmentation::UnicodeSegmentation;
pub trait TextProcessing: UnicodeSegmentation + CodePointsIter { pub trait TextProcessing: UnicodeSegmentation + CodePointsIter {
fn split_graphemes<'a>(&'a self) -> Vec<&'a str> { fn split_graphemes(&self) -> Vec<&str> {
UnicodeSegmentation::graphemes(self, true).collect::<Vec<&str>>() UnicodeSegmentation::graphemes(self, true).collect::<Vec<&str>>()
} }
fn graphemes_indices<'a>(&'a self) -> Vec<(usize, &'a str)> { fn graphemes_indices(&self) -> Vec<(usize, &str)> {
UnicodeSegmentation::grapheme_indices(self, true).collect::<Vec<(usize, &str)>>() UnicodeSegmentation::grapheme_indices(self, true).collect::<Vec<(usize, &str)>>()
} }

View File

@ -128,7 +128,7 @@ trait EvenAfterSpaces {
impl EvenAfterSpaces for str { impl EvenAfterSpaces for str {
fn even_after_spaces(&self) -> &Self { fn even_after_spaces(&self) -> &Self {
let mut ret = self; let mut ret = self;
while !ret.is_empty() && get_class!(&ret) != SP { while !ret.is_empty() && get_class!(ret) != SP {
ret = &ret[get_base_character!(ret).unwrap().len_utf8()..]; ret = &ret[get_base_character!(ret).unwrap().len_utf8()..];
} }
ret ret
@ -173,7 +173,7 @@ impl<'a> Iterator for LineBreakCandidateIter<'a> {
let LineBreakCandidateIter { let LineBreakCandidateIter {
ref mut iter, ref mut iter,
ref text, text,
ref mut reg_ind_streak, ref mut reg_ind_streak,
ref mut break_now, ref mut break_now,
ref mut last_break, ref mut last_break,
@ -996,8 +996,8 @@ mod alg {
let mut p_i = 0; let mut p_i = 0;
while j > 0 { while j > 0 {
let mut line = String::new(); let mut line = String::new();
for i in breaks[j]..j { for word in words.iter().take(j).skip(breaks[j]) {
line.push_str(words[i]); line.push_str(word);
} }
lines.push(line); lines.push(line);
if p_i + 1 < paragraphs { if p_i + 1 < paragraphs {
@ -1110,7 +1110,7 @@ pub fn split_lines_reflow(text: &str, reflow: Reflow, width: Option<usize>) -> V
for (idx, _g) in UnicodeSegmentation::grapheme_indices(line, true) { for (idx, _g) in UnicodeSegmentation::grapheme_indices(line, true) {
t[idx] = 1; t[idx] = 1;
} }
segment_tree::SegmentTree::new(t) Box::new(segment_tree::SegmentTree::new(t))
}; };
let mut prev = 0; let mut prev = 0;
@ -1342,17 +1342,17 @@ pub struct LineBreakText {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum ReflowState { enum ReflowState {
ReflowNo { No {
cur_index: usize, cur_index: usize,
}, },
ReflowAllWidth { AllWidth {
width: usize, width: usize,
state: LineBreakTextState, state: LineBreakTextState,
}, },
ReflowAll { All {
cur_index: usize, cur_index: usize,
}, },
ReflowFormatFlowed { FormatFlowed {
cur_index: usize, cur_index: usize,
}, },
} }
@ -1360,13 +1360,13 @@ enum ReflowState {
impl ReflowState { impl ReflowState {
fn new(reflow: Reflow, width: Option<usize>, cur_index: usize) -> ReflowState { fn new(reflow: Reflow, width: Option<usize>, cur_index: usize) -> ReflowState {
match reflow { match reflow {
Reflow::All if width.is_some() => ReflowState::ReflowAllWidth { Reflow::All if width.is_some() => ReflowState::AllWidth {
width: width.unwrap(), width: width.unwrap(),
state: LineBreakTextState::AtLine { cur_index }, state: LineBreakTextState::AtLine { cur_index },
}, },
Reflow::All => ReflowState::ReflowAll { cur_index }, Reflow::All => ReflowState::All { cur_index },
Reflow::FormatFlowed => ReflowState::ReflowFormatFlowed { cur_index }, Reflow::FormatFlowed => ReflowState::FormatFlowed { cur_index },
Reflow::No => ReflowState::ReflowNo { cur_index }, Reflow::No => ReflowState::No { cur_index },
} }
} }
} }
@ -1382,7 +1382,7 @@ enum LineBreakTextState {
within_line_index: usize, within_line_index: usize,
breaks: Vec<(usize, LineBreakCandidate)>, breaks: Vec<(usize, LineBreakCandidate)>,
prev_break: usize, prev_break: usize,
segment_tree: segment_tree::SegmentTree, segment_tree: Box<segment_tree::SegmentTree>,
}, },
} }
@ -1436,14 +1436,14 @@ impl LineBreakText {
pub fn is_finished(&self) -> bool { pub fn is_finished(&self) -> bool {
match self.state { match self.state {
ReflowState::ReflowNo { cur_index } ReflowState::No { cur_index }
| ReflowState::ReflowAll { cur_index } | ReflowState::All { cur_index }
| ReflowState::ReflowFormatFlowed { cur_index } | ReflowState::FormatFlowed { cur_index }
| ReflowState::ReflowAllWidth { | ReflowState::AllWidth {
width: _, width: _,
state: LineBreakTextState::AtLine { cur_index }, state: LineBreakTextState::AtLine { cur_index },
} => cur_index >= self.text.len(), } => cur_index >= self.text.len(),
ReflowState::ReflowAllWidth { ReflowState::AllWidth {
width: _, width: _,
state: LineBreakTextState::WithinLine { .. }, state: LineBreakTextState::WithinLine { .. },
} => false, } => false,
@ -1461,7 +1461,7 @@ impl Iterator for LineBreakText {
return None; return None;
} }
match self.state { match self.state {
ReflowState::ReflowFormatFlowed { ref mut cur_index } => { ReflowState::FormatFlowed { ref mut cur_index } => {
/* rfc3676 - The Text/Plain Format and DelSp Parameters /* rfc3676 - The Text/Plain Format and DelSp Parameters
* https://tools.ietf.org/html/rfc3676 */ * https://tools.ietf.org/html/rfc3676 */
@ -1575,7 +1575,7 @@ impl Iterator for LineBreakText {
} }
return self.paragraph.pop_front(); return self.paragraph.pop_front();
} }
ReflowState::ReflowAllWidth { ReflowState::AllWidth {
width, width,
ref mut state, ref mut state,
} => { } => {
@ -1624,7 +1624,7 @@ impl Iterator for LineBreakText {
{ {
t[idx] = 1; t[idx] = 1;
} }
segment_tree::SegmentTree::new(t) Box::new(segment_tree::SegmentTree::new(t))
}, },
}; };
if let LineBreakTextState::WithinLine { if let LineBreakTextState::WithinLine {
@ -1740,9 +1740,8 @@ impl Iterator for LineBreakText {
}; };
} }
} }
ReflowState::ReflowNo { ref mut cur_index } ReflowState::No { ref mut cur_index } | ReflowState::All { ref mut cur_index } => {
| ReflowState::ReflowAll { ref mut cur_index } => { if let Some(line) = self.text[*cur_index..].split('\n').next() {
for line in self.text[*cur_index..].split('\n') {
let ret = line.to_string(); let ret = line.to_string();
*cur_index += line.len() + 2; *cur_index += line.len() + 2;
return Some(ret); return Some(ret);

View File

@ -178,17 +178,11 @@ pub trait GlobMatch {
impl GlobMatch for str { impl GlobMatch for str {
fn matches_glob(&self, _pattern: &str) -> bool { fn matches_glob(&self, _pattern: &str) -> bool {
macro_rules! strip_slash { let pattern: Vec<&str> = _pattern
($v:expr) => { .strip_suffix('/')
if $v.ends_with("/") { .unwrap_or(_pattern)
&$v[..$v.len() - 1] .split_graphemes();
} else { let s: Vec<&str> = self.strip_suffix('/').unwrap_or(self).split_graphemes();
$v
}
};
}
let pattern: Vec<&str> = strip_slash!(_pattern).split_graphemes();
let s: Vec<&str> = strip_slash!(self).split_graphemes();
// Taken from https://research.swtch.com/glob // Taken from https://research.swtch.com/glob

View File

@ -1,4 +1,3 @@
use melib;
use melib::email::Draft; use melib::email::Draft;
#[test] #[test]
@ -13,7 +12,7 @@ fn build_draft() {
new_draft.set_body("hello world.".to_string()); new_draft.set_body("hello world.".to_string());
let raw = new_draft.finalise().expect("could not finalise draft"); let raw = new_draft.finalise().expect("could not finalise draft");
let boundary_def = raw.find("bzz_bzz__bzz__").unwrap(); let boundary_def = raw.find("bzz_bzz__bzz__").unwrap();
let boundary_end = boundary_def + raw[boundary_def..].find("\"").unwrap(); let boundary_end = boundary_def + raw[boundary_def..].find('\"').unwrap();
let boundary = raw[boundary_def..boundary_end].to_string(); let boundary = raw[boundary_def..boundary_end].to_string();
let boundary_str = &boundary["bzz_bzz__bzz__".len()..]; let boundary_str = &boundary["bzz_bzz__bzz__".len()..];