Reduce unwrap and expect usage

This commit is contained in:
link2xt
2022-05-21 14:12:23 +00:00
parent 9549aca48b
commit 73341394ee
16 changed files with 134 additions and 130 deletions

View File

@@ -3,7 +3,7 @@
## Unreleased ## Unreleased
### Changes ### Changes
- refactorings #3354 - refactorings #3354 #3347
### Fixes ### Fixes
- do not unnecessarily SELECT folders if there are no operations planned on - do not unnecessarily SELECT folders if there are no operations planned on

View File

@@ -458,7 +458,37 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int
} }
let event = &*event; let event = &*event;
event.as_id() match event.typ {
EventType::Info(_) => 100,
EventType::SmtpConnected(_) => 101,
EventType::ImapConnected(_) => 102,
EventType::SmtpMessageSent(_) => 103,
EventType::ImapMessageDeleted(_) => 104,
EventType::ImapMessageMoved(_) => 105,
EventType::NewBlobFile(_) => 150,
EventType::DeletedBlobFile(_) => 151,
EventType::Warning(_) => 300,
EventType::Error(_) => 400,
EventType::ErrorSelfNotInGroup(_) => 410,
EventType::MsgsChanged { .. } => 2000,
EventType::IncomingMsg { .. } => 2005,
EventType::MsgsNoticed { .. } => 2008,
EventType::MsgDelivered { .. } => 2010,
EventType::MsgFailed { .. } => 2012,
EventType::MsgRead { .. } => 2015,
EventType::ChatModified(_) => 2020,
EventType::ChatEphemeralTimerModified { .. } => 2021,
EventType::ContactsChanged(_) => 2030,
EventType::LocationChanged(_) => 2035,
EventType::ConfigureProgress { .. } => 2041,
EventType::ImexProgress(_) => 2051,
EventType::ImexFileWritten(_) => 2052,
EventType::SecurejoinInviterProgress { .. } => 2060,
EventType::SecurejoinJoinerProgress { .. } => 2061,
EventType::ConnectivityChanged => 2100,
EventType::SelfavatarChanged => 2110,
EventType::WebxdcStatusUpdate { .. } => 2120,
}
} }
#[no_mangle] #[no_mangle]

View File

@@ -141,9 +141,10 @@ impl Accounts {
/// Remove an account. /// Remove an account.
pub async fn remove_account(&mut self, id: u32) -> Result<()> { pub async fn remove_account(&mut self, id: u32) -> Result<()> {
let ctx = self.accounts.remove(&id); let ctx = self
ensure!(ctx.is_some(), "no account with this id: {}", id); .accounts
let ctx = ctx.unwrap(); .remove(&id)
.with_context(|| format!("no account with id {}", id))?;
ctx.stop_io().await; ctx.stop_io().await;
drop(ctx); drop(ctx);

View File

@@ -289,7 +289,7 @@ impl<'a> BlobObject<'a> {
/// Returns the filename of the blob. /// Returns the filename of the blob.
pub fn as_file_name(&self) -> &str { pub fn as_file_name(&self) -> &str {
self.name.rsplit('/').next().unwrap() self.name.rsplit('/').next().unwrap_or_default()
} }
/// The path relative in the blob directory. /// The path relative in the blob directory.

View File

@@ -1441,7 +1441,9 @@ async fn create_or_lookup_group(
return Ok(None); return Ok(None);
} }
let grpname = mime_parser.get_header(HeaderDef::ChatGroupName).unwrap(); let grpname = mime_parser
.get_header(HeaderDef::ChatGroupName)
.context("Chat-Group-Name vanished")?;
let new_chat_id = ChatId::create_multiuser_record( let new_chat_id = ChatId::create_multiuser_record(
context, context,
Chattype::Group, Chattype::Group,

View File

@@ -1,10 +1,7 @@
//! # Events specification. //! # Events specification.
use std::ops::Deref;
use async_std::channel::{self, Receiver, Sender, TrySendError}; use async_std::channel::{self, Receiver, Sender, TrySendError};
use async_std::path::PathBuf; use async_std::path::PathBuf;
use strum::EnumProperty;
use crate::chat::ChatId; use crate::chat::ChatId;
use crate::contact::ContactId; use crate::contact::ContactId;
@@ -92,8 +89,6 @@ impl async_std::stream::Stream for EventEmitter {
/// context emits them in relation to various operations happening, a lot of these are again /// context emits them in relation to various operations happening, a lot of these are again
/// documented in `deltachat.h`. /// documented in `deltachat.h`.
/// ///
/// This struct [`Deref`]s to the [`EventType`].
///
/// [`Context`]: crate::context::Context /// [`Context`]: crate::context::Context
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Event { pub struct Event {
@@ -110,68 +105,39 @@ pub struct Event {
pub typ: EventType, pub typ: EventType,
} }
impl Deref for Event { #[derive(Debug, Clone, PartialEq, Eq)]
type Target = EventType;
fn deref(&self) -> &EventType {
&self.typ
}
}
impl EventType {
/// Returns the corresponding Event ID.
///
/// These are the IDs used in the `DC_EVENT_*` constants in `deltachat.h`.
pub fn as_id(&self) -> i32 {
self.get_str("id")
.expect("missing id")
.parse()
.expect("invalid id")
}
}
#[derive(Debug, Clone, PartialEq, Eq, EnumProperty)]
pub enum EventType { pub enum EventType {
/// The library-user may write an informational string to the log. /// The library-user may write an informational string to the log.
/// ///
/// This event should *not* be reported to the end-user using a popup or something like /// This event should *not* be reported to the end-user using a popup or something like
/// that. /// that.
#[strum(props(id = "100"))]
Info(String), Info(String),
/// Emitted when SMTP connection is established and login was successful. /// Emitted when SMTP connection is established and login was successful.
#[strum(props(id = "101"))]
SmtpConnected(String), SmtpConnected(String),
/// Emitted when IMAP connection is established and login was successful. /// Emitted when IMAP connection is established and login was successful.
#[strum(props(id = "102"))]
ImapConnected(String), ImapConnected(String),
/// Emitted when a message was successfully sent to the SMTP server. /// Emitted when a message was successfully sent to the SMTP server.
#[strum(props(id = "103"))]
SmtpMessageSent(String), SmtpMessageSent(String),
/// Emitted when an IMAP message has been marked as deleted /// Emitted when an IMAP message has been marked as deleted
#[strum(props(id = "104"))]
ImapMessageDeleted(String), ImapMessageDeleted(String),
/// Emitted when an IMAP message has been moved /// Emitted when an IMAP message has been moved
#[strum(props(id = "105"))]
ImapMessageMoved(String), ImapMessageMoved(String),
/// Emitted when an new file in the $BLOBDIR was created /// Emitted when an new file in the $BLOBDIR was created
#[strum(props(id = "150"))]
NewBlobFile(String), NewBlobFile(String),
/// Emitted when an file in the $BLOBDIR was deleted /// Emitted when an file in the $BLOBDIR was deleted
#[strum(props(id = "151"))]
DeletedBlobFile(String), DeletedBlobFile(String),
/// The library-user should write a warning string to the log. /// The library-user should write a warning string to the log.
/// ///
/// This event should *not* be reported to the end-user using a popup or something like /// This event should *not* be reported to the end-user using a popup or something like
/// that. /// that.
#[strum(props(id = "300"))]
Warning(String), Warning(String),
/// The library-user should report an error to the end-user. /// The library-user should report an error to the end-user.
@@ -184,7 +150,6 @@ pub enum EventType {
/// it might be better to delay showing these events until the function has really /// it might be better to delay showing these events until the function has really
/// failed (returned false). It should be sufficient to report only the *last* error /// failed (returned false). It should be sufficient to report only the *last* error
/// in a messasge box then. /// in a messasge box then.
#[strum(props(id = "400"))]
Error(String), Error(String),
/// An action cannot be performed because the user is not in the group. /// An action cannot be performed because the user is not in the group.
@@ -192,7 +157,6 @@ pub enum EventType {
/// dc_set_chat_name(), dc_set_chat_profile_image(), /// dc_set_chat_name(), dc_set_chat_profile_image(),
/// dc_add_contact_to_chat(), dc_remove_contact_from_chat(), /// dc_add_contact_to_chat(), dc_remove_contact_from_chat(),
/// dc_send_text_msg() or another sending function. /// dc_send_text_msg() or another sending function.
#[strum(props(id = "410"))]
ErrorSelfNotInGroup(String), ErrorSelfNotInGroup(String),
/// Messages or chats changed. One or more messages or chats changed for various /// Messages or chats changed. One or more messages or chats changed for various
@@ -203,35 +167,44 @@ pub enum EventType {
/// ///
/// `chat_id` is set if only a single chat is affected by the changes, otherwise 0. /// `chat_id` is set if only a single chat is affected by the changes, otherwise 0.
/// `msg_id` is set if only a single message is affected by the changes, otherwise 0. /// `msg_id` is set if only a single message is affected by the changes, otherwise 0.
#[strum(props(id = "2000"))] MsgsChanged {
MsgsChanged { chat_id: ChatId, msg_id: MsgId }, chat_id: ChatId,
msg_id: MsgId,
},
/// There is a fresh message. Typically, the user will show an notification /// There is a fresh message. Typically, the user will show an notification
/// when receiving this message. /// when receiving this message.
/// ///
/// There is no extra #DC_EVENT_MSGS_CHANGED event send together with this event. /// There is no extra #DC_EVENT_MSGS_CHANGED event send together with this event.
#[strum(props(id = "2005"))] IncomingMsg {
IncomingMsg { chat_id: ChatId, msg_id: MsgId }, chat_id: ChatId,
msg_id: MsgId,
},
/// Messages were seen or noticed. /// Messages were seen or noticed.
/// chat id is always set. /// chat id is always set.
#[strum(props(id = "2008"))]
MsgsNoticed(ChatId), MsgsNoticed(ChatId),
/// A single message is sent successfully. State changed from DC_STATE_OUT_PENDING to /// A single message is sent successfully. State changed from DC_STATE_OUT_PENDING to
/// DC_STATE_OUT_DELIVERED, see dc_msg_get_state(). /// DC_STATE_OUT_DELIVERED, see dc_msg_get_state().
#[strum(props(id = "2010"))] MsgDelivered {
MsgDelivered { chat_id: ChatId, msg_id: MsgId }, chat_id: ChatId,
msg_id: MsgId,
},
/// A single message could not be sent. State changed from DC_STATE_OUT_PENDING or DC_STATE_OUT_DELIVERED to /// A single message could not be sent. State changed from DC_STATE_OUT_PENDING or DC_STATE_OUT_DELIVERED to
/// DC_STATE_OUT_FAILED, see dc_msg_get_state(). /// DC_STATE_OUT_FAILED, see dc_msg_get_state().
#[strum(props(id = "2012"))] MsgFailed {
MsgFailed { chat_id: ChatId, msg_id: MsgId }, chat_id: ChatId,
msg_id: MsgId,
},
/// A single message is read by the receiver. State changed from DC_STATE_OUT_DELIVERED to /// A single message is read by the receiver. State changed from DC_STATE_OUT_DELIVERED to
/// DC_STATE_OUT_MDN_RCVD, see dc_msg_get_state(). /// DC_STATE_OUT_MDN_RCVD, see dc_msg_get_state().
#[strum(props(id = "2015"))] MsgRead {
MsgRead { chat_id: ChatId, msg_id: MsgId }, chat_id: ChatId,
msg_id: MsgId,
},
/// Chat changed. The name or the image of a chat group was changed or members were added or removed. /// Chat changed. The name or the image of a chat group was changed or members were added or removed.
/// Or the verify state of a chat has changed. /// Or the verify state of a chat has changed.
@@ -240,11 +213,9 @@ pub enum EventType {
/// ///
/// This event does not include ephemeral timer modification, which /// This event does not include ephemeral timer modification, which
/// is a separate event. /// is a separate event.
#[strum(props(id = "2020"))]
ChatModified(ChatId), ChatModified(ChatId),
/// Chat ephemeral timer changed. /// Chat ephemeral timer changed.
#[strum(props(id = "2021"))]
ChatEphemeralTimerModified { ChatEphemeralTimerModified {
chat_id: ChatId, chat_id: ChatId,
timer: EphemeralTimer, timer: EphemeralTimer,
@@ -253,7 +224,6 @@ pub enum EventType {
/// Contact(s) created, renamed, blocked or deleted. /// Contact(s) created, renamed, blocked or deleted.
/// ///
/// @param data1 (int) If set, this is the contact_id of an added contact that should be selected. /// @param data1 (int) If set, this is the contact_id of an added contact that should be selected.
#[strum(props(id = "2030"))]
ContactsChanged(Option<ContactId>), ContactsChanged(Option<ContactId>),
/// Location of one or more contact has changed. /// Location of one or more contact has changed.
@@ -261,11 +231,9 @@ pub enum EventType {
/// @param data1 (u32) contact_id of the contact for which the location has changed. /// @param data1 (u32) contact_id of the contact for which the location has changed.
/// If the locations of several contacts have been changed, /// If the locations of several contacts have been changed,
/// eg. after calling dc_delete_all_locations(), this parameter is set to `None`. /// eg. after calling dc_delete_all_locations(), this parameter is set to `None`.
#[strum(props(id = "2035"))]
LocationChanged(Option<ContactId>), LocationChanged(Option<ContactId>),
/// Inform about the configuration progress started by configure(). /// Inform about the configuration progress started by configure().
#[strum(props(id = "2041"))]
ConfigureProgress { ConfigureProgress {
/// Progress. /// Progress.
/// ///
@@ -280,7 +248,6 @@ pub enum EventType {
/// ///
/// @param data1 (usize) 0=error, 1-999=progress in permille, 1000=success and done /// @param data1 (usize) 0=error, 1-999=progress in permille, 1000=success and done
/// @param data2 0 /// @param data2 0
#[strum(props(id = "2051"))]
ImexProgress(usize), ImexProgress(usize),
/// A file has been exported. A file has been written by imex(). /// A file has been exported. A file has been written by imex().
@@ -290,7 +257,6 @@ pub enum EventType {
/// services. /// services.
/// ///
/// @param data2 0 /// @param data2 0
#[strum(props(id = "2052"))]
ImexFileWritten(PathBuf), ImexFileWritten(PathBuf),
/// Progress information of a secure-join handshake from the view of the inviter /// Progress information of a secure-join handshake from the view of the inviter
@@ -305,7 +271,6 @@ pub enum EventType {
/// 600=vg-/vc-request-with-auth received, vg-member-added/vc-contact-confirm sent, typically shown as "bob@addr verified". /// 600=vg-/vc-request-with-auth received, vg-member-added/vc-contact-confirm sent, typically shown as "bob@addr verified".
/// 800=vg-member-added-received received, shown as "bob@addr securely joined GROUP", only sent for the verified-group-protocol. /// 800=vg-member-added-received received, shown as "bob@addr securely joined GROUP", only sent for the verified-group-protocol.
/// 1000=Protocol finished for this contact. /// 1000=Protocol finished for this contact.
#[strum(props(id = "2060"))]
SecurejoinInviterProgress { SecurejoinInviterProgress {
contact_id: ContactId, contact_id: ContactId,
progress: usize, progress: usize,
@@ -319,7 +284,6 @@ pub enum EventType {
/// @param data2 (int) Progress as: /// @param data2 (int) Progress as:
/// 400=vg-/vc-request-with-auth sent, typically shown as "alice@addr verified, introducing myself." /// 400=vg-/vc-request-with-auth sent, typically shown as "alice@addr verified, introducing myself."
/// (Bob has verified alice and waits until Alice does the same for him) /// (Bob has verified alice and waits until Alice does the same for him)
#[strum(props(id = "2061"))]
SecurejoinJoinerProgress { SecurejoinJoinerProgress {
contact_id: ContactId, contact_id: ContactId,
progress: usize, progress: usize,
@@ -329,13 +293,10 @@ pub enum EventType {
/// This means that you should refresh the connectivity view /// This means that you should refresh the connectivity view
/// and possibly the connectivtiy HTML; see dc_get_connectivity() and /// and possibly the connectivtiy HTML; see dc_get_connectivity() and
/// dc_get_connectivity_html() for details. /// dc_get_connectivity_html() for details.
#[strum(props(id = "2100"))]
ConnectivityChanged, ConnectivityChanged,
#[strum(props(id = "2110"))]
SelfavatarChanged, SelfavatarChanged,
#[strum(props(id = "2120"))]
WebxdcStatusUpdate { WebxdcStatusUpdate {
msg_id: MsgId, msg_id: MsgId,
status_update_serial: StatusUpdateSerial, status_update_serial: StatusUpdateSerial,

View File

@@ -11,7 +11,7 @@ use futures::future::FutureExt;
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use anyhow::Result; use anyhow::{Context as _, Result};
use lettre_email::mime::{self, Mime}; use lettre_email::mime::{self, Mime};
use crate::headerdef::{HeaderDef, HeaderDefMap}; use crate::headerdef::{HeaderDef, HeaderDefMap};
@@ -134,7 +134,7 @@ impl HtmlMsgParser {
if raw.is_empty() { if raw.is_empty() {
return Ok(()); return Ok(());
} }
let mail = mailparse::parse_mail(&raw).unwrap(); let mail = mailparse::parse_mail(&raw).context("failed to parse mail")?;
self.collect_texts_recursive(context, &mail).await self.collect_texts_recursive(context, &mail).await
} }
MimeMultipartType::Single => { MimeMultipartType::Single => {
@@ -190,7 +190,7 @@ impl HtmlMsgParser {
if raw.is_empty() { if raw.is_empty() {
return Ok(()); return Ok(());
} }
let mail = mailparse::parse_mail(&raw).unwrap(); let mail = mailparse::parse_mail(&raw).context("failed to parse mail")?;
self.cid_to_data_recursive(context, &mail).await self.cid_to_data_recursive(context, &mail).await
} }
MimeMultipartType::Single => { MimeMultipartType::Single => {

View File

@@ -4,7 +4,7 @@ use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use std::io::Cursor; use std::io::Cursor;
use anyhow::{format_err, Context as _, Result}; use anyhow::{ensure, Context as _, Result};
use async_trait::async_trait; use async_trait::async_trait;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use pgp::composed::Deserializable; use pgp::composed::Deserializable;
@@ -82,7 +82,7 @@ pub trait DcKey: Serialize + Deserializable + KeyTrait + Clone {
/// The fingerprint for the key. /// The fingerprint for the key.
fn fingerprint(&self) -> Fingerprint { fn fingerprint(&self) -> Fingerprint {
Fingerprint::new(KeyTrait::fingerprint(self)).expect("Invalid fingerprint from rpgp") Fingerprint::new(KeyTrait::fingerprint(self))
} }
} }
@@ -320,11 +320,9 @@ pub async fn store_self_keypair(
pub struct Fingerprint(Vec<u8>); pub struct Fingerprint(Vec<u8>);
impl Fingerprint { impl Fingerprint {
pub fn new(v: Vec<u8>) -> Result<Fingerprint> { pub fn new(v: Vec<u8>) -> Fingerprint {
match v.len() { debug_assert_eq!(v.len(), 20);
20 => Ok(Fingerprint(v)), Fingerprint(v)
_ => Err(format_err!("Wrong fingerprint length")),
}
} }
/// Make a hex string from the fingerprint. /// Make a hex string from the fingerprint.
@@ -364,14 +362,15 @@ impl fmt::Display for Fingerprint {
impl std::str::FromStr for Fingerprint { impl std::str::FromStr for Fingerprint {
type Err = anyhow::Error; type Err = anyhow::Error;
fn from_str(input: &str) -> std::result::Result<Self, Self::Err> { fn from_str(input: &str) -> Result<Self> {
let hex_repr: String = input let hex_repr: String = input
.to_uppercase() .to_uppercase()
.chars() .chars()
.filter(|&c| ('0'..='9').contains(&c) || ('A'..='F').contains(&c)) .filter(|&c| ('0'..='9').contains(&c) || ('A'..='F').contains(&c))
.collect(); .collect();
let v: Vec<u8> = hex::decode(hex_repr)?; let v: Vec<u8> = hex::decode(&hex_repr)?;
let fp = Fingerprint::new(v)?; ensure!(v.len() == 20, "wrong fingerprint length: {}", hex_repr);
let fp = Fingerprint::new(v);
Ok(fp) Ok(fp)
} }
} }
@@ -589,8 +588,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
fn test_fingerprint_from_str() { fn test_fingerprint_from_str() {
let res = Fingerprint::new(vec![ let res = Fingerprint::new(vec![
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
]) ]);
.unwrap();
let fp: Fingerprint = "0102030405060708090A0B0c0d0e0F1011121314".parse().unwrap(); let fp: Fingerprint = "0102030405060708090A0B0c0d0e0F1011121314".parse().unwrap();
assert_eq!(fp, res); assert_eq!(fp, res);
@@ -607,8 +605,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
fn test_fingerprint_hex() { fn test_fingerprint_hex() {
let fp = Fingerprint::new(vec![ let fp = Fingerprint::new(vec![
1, 2, 4, 8, 16, 32, 64, 128, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 2, 4, 8, 16, 32, 64, 128, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
]) ]);
.unwrap();
assert_eq!(fp.hex(), "0102040810204080FF0A0B0C0D0E0F1011121314"); assert_eq!(fp.hex(), "0102040810204080FF0A0B0C0D0E0F1011121314");
} }
@@ -616,8 +613,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
fn test_fingerprint_to_string() { fn test_fingerprint_to_string() {
let fp = Fingerprint::new(vec![ let fp = Fingerprint::new(vec![
1, 2, 4, 8, 16, 32, 64, 128, 255, 1, 2, 4, 8, 16, 32, 64, 128, 255, 19, 20, 1, 2, 4, 8, 16, 32, 64, 128, 255, 1, 2, 4, 8, 16, 32, 64, 128, 255, 19, 20,
]) ]);
.unwrap();
assert_eq!( assert_eq!(
fp.to_string(), fp.to_string(),
"0102 0408 1020 4080 FF01\n0204 0810 2040 80FF 1314" "0102 0408 1020 4080 FF01\n0204 0810 2040 80FF 1314"

View File

@@ -8,7 +8,9 @@
clippy::indexing_slicing, clippy::indexing_slicing,
clippy::wildcard_imports, clippy::wildcard_imports,
clippy::needless_borrow, clippy::needless_borrow,
clippy::cast_lossless clippy::cast_lossless,
clippy::unwrap_used,
clippy::expect_used
)] )]
#![allow( #![allow(
clippy::match_bool, clippy::match_bool,

View File

@@ -153,12 +153,12 @@ impl Kml {
) { ) {
let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase();
if tag == "document" { if tag == "document" {
if let Some(addr) = event.attributes().find(|attr| { if let Some(addr) = event
attr.as_ref() .attributes()
.map(|a| String::from_utf8_lossy(a.key).trim().to_lowercase() == "addr") .filter_map(|a| a.ok())
.unwrap_or_default() .find(|attr| String::from_utf8_lossy(attr.key).trim().to_lowercase() == "addr")
}) { {
self.addr = addr.unwrap().unescape_and_decode_value(reader).ok(); self.addr = addr.unescape_and_decode_value(reader).ok();
} }
} else if tag == "placemark" { } else if tag == "placemark" {
self.tag = KmlTag::PLACEMARK; self.tag = KmlTag::PLACEMARK;

View File

@@ -210,7 +210,7 @@ impl LoginParam {
let key = format!("{}smtp_certificate_checks", prefix); let key = format!("{}smtp_certificate_checks", prefix);
let smtp_certificate_checks = let smtp_certificate_checks =
if let Some(certificate_checks) = sql.get_raw_config_int(key).await? { if let Some(certificate_checks) = sql.get_raw_config_int(key).await? {
num_traits::FromPrimitive::from_i32(certificate_checks).unwrap() num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default()
} else { } else {
Default::default() Default::default()
}; };

View File

@@ -5,7 +5,7 @@ use std::future::Future;
use std::io::Cursor; use std::io::Cursor;
use std::pin::Pin; use std::pin::Pin;
use anyhow::{bail, Result}; use anyhow::{bail, Context as _, Result};
use deltachat_derive::{FromSql, ToSql}; use deltachat_derive::{FromSql, ToSql};
use lettre_email::mime::{self, Mime}; use lettre_email::mime::{self, Mime};
use mailparse::{addrparse_header, DispositionType, MailHeader, MailHeaderMap, SingleInfo}; use mailparse::{addrparse_header, DispositionType, MailHeader, MailHeaderMap, SingleInfo};
@@ -715,7 +715,7 @@ impl MimeMessage {
if raw.is_empty() { if raw.is_empty() {
return Ok(false); return Ok(false);
} }
let mail = mailparse::parse_mail(&raw).unwrap(); let mail = mailparse::parse_mail(&raw).context("failed to parse mail")?;
self.parse_mime_recursive(context, &mail, is_related).await self.parse_mime_recursive(context, &mail, is_related).await
} }

View File

@@ -146,8 +146,10 @@ pub async fn dc_get_oauth2_access_token(
value = &redirect_uri; value = &redirect_uri;
} else if value == "$CODE" { } else if value == "$CODE" {
value = code; value = code;
} else if value == "$REFRESH_TOKEN" && refresh_token.is_some() { } else if value == "$REFRESH_TOKEN" {
value = refresh_token.as_ref().unwrap(); if let Some(refresh_token) = refresh_token.as_ref() {
value = refresh_token;
}
} }
post_param.insert(key, value); post_param.insert(key, value);
@@ -162,16 +164,18 @@ pub async fn dc_get_oauth2_access_token(
let client = surf::Client::new(); let client = surf::Client::new();
let parsed: Result<Response, _> = client.recv_json(req).await; let parsed: Result<Response, _> = client.recv_json(req).await;
if parsed.is_err() { let response = match parsed {
Ok(response) => response,
Err(err) => {
warn!( warn!(
context, context,
"Failed to parse OAuth2 JSON response from {}: error: {:?}", token_url, parsed "Failed to parse OAuth2 JSON response from {}: error: {}", token_url, err
); );
return Ok(None); return Ok(None);
} }
};
// update refresh_token if given, typically on the first round, but we update it later as well. // update refresh_token if given, typically on the first round, but we update it later as well.
let response = parsed.unwrap();
if let Some(ref token) = response.refresh_token { if let Some(ref token) = response.refresh_token {
context context
.sql .sql
@@ -286,12 +290,13 @@ impl Oauth2 {
// } // }
let response: Result<HashMap<String, serde_json::Value>, surf::Error> = let response: Result<HashMap<String, serde_json::Value>, surf::Error> =
surf::get(userinfo_url).recv_json().await; surf::get(userinfo_url).recv_json().await;
if response.is_err() { let parsed = match response {
warn!(context, "Error getting userinfo: {:?}", response); Ok(parsed) => parsed,
Err(err) => {
warn!(context, "Error getting userinfo: {}", err);
return None; return None;
} }
};
let parsed = response.unwrap();
// CAVE: serde_json::Value.as_str() removes the quotes of json-strings // CAVE: serde_json::Value.as_str() removes the quotes of json-strings
// but serde_json::Value.to_string() does not! // but serde_json::Value.to_string() does not!
if let Some(addr) = parsed.get("email") { if let Some(addr) = parsed.get("email") {

View File

@@ -4,7 +4,7 @@ use std::collections::{BTreeMap, HashSet};
use std::io; use std::io;
use std::io::Cursor; use std::io::Cursor;
use anyhow::{bail, ensure, format_err, Context as _, Result}; use anyhow::{bail, format_err, Context as _, Result};
use pgp::armor::BlockType; use pgp::armor::BlockType;
use pgp::composed::{ use pgp::composed::{
Deserializable, KeyType as PgpKeyType, Message, SecretKeyParamsBuilder, SignedPublicKey, Deserializable, KeyType as PgpKeyType, Message, SecretKeyParamsBuilder, SignedPublicKey,
@@ -98,9 +98,7 @@ pub fn split_armored_data(buf: &[u8]) -> Result<(BlockType, BTreeMap<String, Str
let mut bytes = Vec::with_capacity(buf.len()); let mut bytes = Vec::with_capacity(buf.len());
dearmor.read_to_end(&mut bytes)?; dearmor.read_to_end(&mut bytes)?;
ensure!(dearmor.typ.is_some(), "Failed to parse type"); let typ = dearmor.typ.context("failed to parse type")?;
let typ = dearmor.typ.unwrap();
// normalize headers // normalize headers
let headers = dearmor let headers = dearmor
@@ -183,10 +181,12 @@ pub(crate) fn create_keypair(
.can_encrypt(true) .can_encrypt(true)
.passphrase(None) .passphrase(None)
.build() .build()
.unwrap(), .map_err(|err| {
PgpKeygenError::new("failed to build subkey parameters", format_err!("{}", err))
})?,
) )
.build() .build()
.map_err(|err| PgpKeygenError::new("invalid key params", format_err!(err)))?; .map_err(|err| PgpKeygenError::new("invalid key params", format_err!("{}", err)))?;
let key = key_params let key = key_params
.generate() .generate()
.map_err(|err| PgpKeygenError::new("invalid params", err))?; .map_err(|err| PgpKeygenError::new("invalid params", err))?;

View File

@@ -245,8 +245,11 @@ async fn fingerprint_equals_sender(
}; };
if let Some(peerstate) = peerstate { if let Some(peerstate) = peerstate {
if peerstate.public_key_fingerprint.is_some() if peerstate
&& fingerprint == peerstate.public_key_fingerprint.as_ref().unwrap() .public_key_fingerprint
.as_ref()
.filter(|&fp| fp == fingerprint)
.is_some()
{ {
return Ok(true); return Ok(true);
} }

View File

@@ -702,13 +702,15 @@ pub async fn remove_unused_files(context: &Context) -> Result<()> {
Ok(mut dir_handle) => { Ok(mut dir_handle) => {
/* avoid deletion of files that are just created to build a message object */ /* avoid deletion of files that are just created to build a message object */
let diff = std::time::Duration::from_secs(60 * 60); let diff = std::time::Duration::from_secs(60 * 60);
let keep_files_newer_than = std::time::SystemTime::now().checked_sub(diff).unwrap(); let keep_files_newer_than = std::time::SystemTime::now()
.checked_sub(diff)
.unwrap_or(std::time::SystemTime::UNIX_EPOCH);
while let Some(entry) = dir_handle.next().await { while let Some(entry) = dir_handle.next().await {
if entry.is_err() { let entry = match entry {
break; Ok(entry) => entry,
} Err(_) => break,
let entry = entry.unwrap(); };
let name_f = entry.file_name(); let name_f = entry.file_name();
let name_s = name_f.to_string_lossy(); let name_s = name_f.to_string_lossy();
@@ -724,11 +726,13 @@ pub async fn remove_unused_files(context: &Context) -> Result<()> {
if let Ok(stats) = async_std::fs::metadata(entry.path()).await { if let Ok(stats) = async_std::fs::metadata(entry.path()).await {
let recently_created = let recently_created =
stats.created().is_ok() && stats.created().unwrap() > keep_files_newer_than; stats.created().map_or(false, |t| t > keep_files_newer_than);
let recently_modified = stats.modified().is_ok() let recently_modified = stats
&& stats.modified().unwrap() > keep_files_newer_than; .modified()
let recently_accessed = stats.accessed().is_ok() .map_or(false, |t| t > keep_files_newer_than);
&& stats.accessed().unwrap() > keep_files_newer_than; let recently_accessed = stats
.accessed()
.map_or(false, |t| t > keep_files_newer_than);
if recently_created || recently_modified || recently_accessed { if recently_created || recently_modified || recently_accessed {
info!( info!(