make enum reading from the db more robust

This commit is contained in:
dignifiedquire
2019-09-08 11:29:40 +02:00
parent d07ef01204
commit 00e5ddd6f0
5 changed files with 52 additions and 21 deletions

View File

@@ -36,7 +36,7 @@ pub fn from_sql_derive(input: TokenStream) -> TokenStream {
impl rusqlite::types::FromSql for #name {
fn column_result(col: rusqlite::types::ValueRef) -> rusqlite::types::FromSqlResult<Self> {
let inner = rusqlite::types::FromSql::column_result(col)?;
num_traits::FromPrimitive::from_i64(inner).ok_or(rusqlite::types::FromSqlError::InvalidType)
Ok(num_traits::FromPrimitive::from_i64(inner).unwrap_or_default())
}
}
};

View File

@@ -18,6 +18,12 @@ pub enum MoveState {
Moving = 3,
}
impl Default for MoveState {
fn default() -> Self {
MoveState::Undefined
}
}
// some defaults
const DC_E2EE_DEFAULT_ENABLED: i32 = 1;
pub const DC_MDNS_DEFAULT_ENABLED: i32 = 1;
@@ -220,6 +226,12 @@ pub enum Viewtype {
File = 60,
}
impl Default for Viewtype {
fn default() -> Self {
Viewtype::Unknown
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -1,7 +1,6 @@
use deltachat_derive::*;
use itertools::Itertools;
use num_traits::{FromPrimitive, ToPrimitive};
use rusqlite;
use rusqlite::types::*;
use crate::aheader::EncryptPreference;
use crate::config::Config;
@@ -58,7 +57,9 @@ pub struct Contact<'a> {
}
/// Possible origins of a contact.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromPrimitive, ToPrimitive)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromPrimitive, ToPrimitive, FromSql, ToSql,
)]
#[repr(i32)]
pub enum Origin {
Unknown = 0,
@@ -96,23 +97,9 @@ pub enum Origin {
ManuallyCreated = 0x4000000,
}
impl ToSql for Origin {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
let num: i64 = self
.to_i64()
.expect("impossible: Origin -> i64 conversion failed");
Ok(ToSqlOutput::Owned(Value::Integer(num)))
}
}
impl FromSql for Origin {
fn column_result(col: ValueRef) -> FromSqlResult<Self> {
let inner = FromSql::column_result(col)?;
match FromPrimitive::from_i64(inner) {
Some(res) => Ok(res),
None => Ok(Origin::Unknown),
}
impl Default for Origin {
fn default() -> Self {
Origin::Unknown
}
}

View File

@@ -25,13 +25,22 @@ use crate::x::*;
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)]
#[repr(i32)]
enum Thread {
Unknown = 0,
Imap = 100,
Smtp = 5000,
}
impl Default for Thread {
fn default() -> Self {
Thread::Unknown
}
}
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)]
#[repr(i32)]
pub enum Action {
Unknown = 0,
// Jobs in the INBOX-thread, range from DC_IMAP_THREAD..DC_IMAP_THREAD+999
Housekeeping = 105, // low priority ...
DeleteMsgOnImap = 110,
@@ -50,11 +59,19 @@ pub enum Action {
SendMsgToSmtp = 5901, // ... high priority
}
impl Default for Action {
fn default() -> Self {
Action::Unknown
}
}
impl From<Action> for Thread {
fn from(action: Action) -> Thread {
use Action::*;
match action {
Unknown => Thread::Unknown,
Housekeeping => Thread::Imap,
DeleteMsgOnImap => Thread::Imap,
MarkseenMdnOnImap => Thread::Imap,
@@ -844,6 +861,9 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) {
job.try_again = 0;
match job.action {
Action::Unknown => {
warn!(context, 0, "Unknown job id found");
}
Action::SendMsgToSmtp => job.do_DC_JOB_SEND(context),
Action::DeleteMsgOnImap => job.do_DC_JOB_DELETE_MSG_ON_IMAP(context),
Action::MarkseenMsgOnImap => job.do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context),
@@ -1062,6 +1082,11 @@ pub fn job_add(
param: Params,
delay_seconds: i64,
) {
if action != Action::Unknown {
error!(context, 0, "Invalid action passed to job_add");
return;
}
let timestamp = time();
let thread: Thread = action.into();
@@ -1082,6 +1107,7 @@ pub fn job_add(
match thread {
Thread::Imap => interrupt_imap_idle(context),
Thread::Smtp => interrupt_smtp_idle(context),
Thread::Unknown => {}
}
}

View File

@@ -38,6 +38,12 @@ pub enum MessageState {
OutMdnRcvd = 28,
}
impl Default for MessageState {
fn default() -> Self {
MessageState::Undefined
}
}
impl From<MessageState> for LotState {
fn from(s: MessageState) -> Self {
use MessageState::*;