diff --git a/Cargo.lock b/Cargo.lock index 1a1738981..ca7f78e6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -507,6 +507,7 @@ dependencies = [ "deltachat 1.0.0-alpha.3", "human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/deltachat-ffi/Cargo.toml b/deltachat-ffi/Cargo.toml index c4e0d8580..ad4a79228 100644 --- a/deltachat-ffi/Cargo.toml +++ b/deltachat-ffi/Cargo.toml @@ -18,6 +18,7 @@ crate-type = ["cdylib", "staticlib"] deltachat = { path = "../", default-features = false } libc = "0.2" human-panic = "1.0.1" +num-traits = "0.2.6" [features] default = ["vendored", "nightly", "ringbuf"] diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 3cef3ef07..045053044 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -9,7 +9,10 @@ #[macro_use] extern crate human_panic; +extern crate num_traits; +use num_traits::{FromPrimitive, ToPrimitive}; +use std::ptr; use std::str::FromStr; use deltachat::*; @@ -458,6 +461,14 @@ pub unsafe extern "C" fn dc_marknoticed_all_chats(context: *mut dc_context_t) { dc_chat::dc_marknoticed_all_chats(context); } +fn from_prim(s: S) -> Option +where + T: FromPrimitive, + S: Into, +{ + FromPrimitive::from_i64(s.into()) +} + #[no_mangle] pub unsafe extern "C" fn dc_get_chat_media( context: *mut dc_context_t, @@ -469,7 +480,15 @@ pub unsafe extern "C" fn dc_get_chat_media( assert!(!context.is_null()); let context = &*context; - dc_chat::dc_get_chat_media(context, chat_id, msg_type, or_msg_type2, or_msg_type3) + if let (Some(msg_type), Some(or_msg_type2), Some(or_msg_type3)) = ( + from_prim(msg_type), + from_prim(or_msg_type2), + from_prim(or_msg_type3), + ) { + dc_chat::dc_get_chat_media(context, chat_id, msg_type, or_msg_type2, or_msg_type3) + } else { + ptr::null_mut() + } } #[no_mangle] @@ -484,7 +503,15 @@ pub unsafe extern "C" fn dc_get_next_media( assert!(!context.is_null()); let context = &*context; - dc_chat::dc_get_next_media(context, msg_id, dir, msg_type, or_msg_type2, or_msg_type3) + if let (Some(msg_type), Some(or_msg_type2), Some(or_msg_type3)) = ( + from_prim(msg_type), + from_prim(or_msg_type2), + from_prim(or_msg_type3), + ) { + dc_chat::dc_get_next_media(context, msg_id, dir, msg_type, or_msg_type2, or_msg_type3) + } else { + 0 + } } #[no_mangle] @@ -1236,8 +1263,11 @@ pub unsafe extern "C" fn dc_msg_new<'a>( ) -> *mut dc_msg::dc_msg_t<'a> { assert!(!context.is_null()); let context = &*context; - - dc_msg::dc_msg_new(context, viewtype) + if let Some(viewtype) = from_prim(viewtype) { + dc_msg::dc_msg_new(context, viewtype) + } else { + ptr::null_mut() + } } #[no_mangle] @@ -1268,6 +1298,8 @@ pub unsafe extern "C" fn dc_msg_get_chat_id(msg: *mut dc_msg::dc_msg_t) -> u32 { #[no_mangle] pub unsafe extern "C" fn dc_msg_get_viewtype(msg: *mut dc_msg::dc_msg_t) -> libc::c_int { dc_msg::dc_msg_get_viewtype(msg) + .to_i64() + .expect("impossible: Viewtype -> i64 conversion failed") as libc::c_int } #[no_mangle] diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 960446fa5..f6bcb083d 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -963,7 +963,14 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(!sel_chat.is_null(), "No chat selected."); ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given."); - let msg_0 = dc_msg_new(context, if arg0 == "sendimage" { 20 } else { 60 }); + let msg_0 = dc_msg_new( + context, + if arg0 == "sendimage" { + Viewtype::Image + } else { + Viewtype::File + }, + ); dc_msg_set_file(msg_0, arg1_c, 0 as *const libc::c_char); dc_msg_set_text(msg_0, arg2_c); dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0); @@ -990,7 +997,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(!sel_chat.is_null(), "No chat selected."); if !arg1.is_empty() { - let draft_0 = dc_msg_new(context, 10); + let draft_0 = dc_msg_new(context, Viewtype::Text); dc_msg_set_text(draft_0, arg1_c); dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0); dc_msg_unref(draft_0); @@ -1003,7 +1010,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E "listmedia" => { ensure!(!sel_chat.is_null(), "No chat selected."); - let images = dc_get_chat_media(context, dc_chat_get_id(sel_chat), 20, 21, 50); + let images = dc_get_chat_media( + context, + dc_chat_get_id(sel_chat), + Viewtype::Image, + Viewtype::Gif, + Viewtype::Video, + ); let icnt: libc::c_int = dc_array_get_cnt(images) as libc::c_int; println!("{} images or videos: ", icnt); for i in 0..icnt { diff --git a/src/constants.rs b/src/constants.rs index e1eb5b835..e72019174 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,5 +1,9 @@ -#![allow(non_camel_case_types)] //! Constants +#![allow(non_camel_case_types)] +use num_traits::{FromPrimitive, ToPrimitive}; +use rusqlite as sql; +use rusqlite::types::*; +use std::fmt; pub const DC_VERSION_STR: &'static [u8; 14] = b"1.0.0-alpha.3\x00"; @@ -96,46 +100,6 @@ pub const DC_TEXT1_SELF: usize = 3; pub const DC_CREATE_MVBOX: usize = 1; -/// Text message. -/// The text of the message is set using dc_msg_set_text() -/// and retrieved with dc_msg_get_text(). -pub const DC_MSG_TEXT: i32 = 10; - -/// Image message. -/// If the image is an animated GIF, the type DC_MSG_GIF should be used. -/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension -/// and retrieved via dc_msg_set_file(), dc_msg_set_dimension(). -pub const DC_MSG_IMAGE: i32 = 20; - -/// Animated GIF message. -/// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension() -/// and retrieved via dc_msg_get_file(), dc_msg_get_width(), dc_msg_get_height(). -pub const DC_MSG_GIF: i32 = 21; - -/// Message containing an Audio file. -/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration() -/// and retrieved via dc_msg_get_file(), dc_msg_get_duration(). -pub const DC_MSG_AUDIO: i32 = 40; - -/// A voice message that was directly recorded by the user. -/// For all other audio messages, the type #DC_MSG_AUDIO should be used. -/// File and duration are set via dc_msg_set_file(), dc_msg_set_duration() -/// and retrieved via dc_msg_get_file(), dc_msg_get_duration() -pub const DC_MSG_VOICE: i32 = 41; - -/// Video messages. -/// File, width, height and durarion -/// are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration() -/// and retrieved via -/// dc_msg_get_file(), dc_msg_get_width(), -/// dc_msg_get_height(), dc_msg_get_duration(). -pub const DC_MSG_VIDEO: i32 = 50; - -/// Message containing any file, eg. a PDF. -/// The file is set via dc_msg_set_file() -/// and retrieved via dc_msg_get_file(). -pub const DC_MSG_FILE: i32 = 60; - // Flags for configuring IMAP and SMTP servers. // These flags are optional // and may be set together with the username, password etc. @@ -183,6 +147,79 @@ pub const DC_LP_IMAP_SOCKET_FLAGS: usize = pub const DC_LP_SMTP_SOCKET_FLAGS: usize = (DC_LP_SMTP_SOCKET_STARTTLS | DC_LP_SMTP_SOCKET_SSL | DC_LP_SMTP_SOCKET_PLAIN); +#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)] +#[repr(i32)] +pub enum Viewtype { + Unknown = 0, + /// Text message. + /// The text of the message is set using dc_msg_set_text() + /// and retrieved with dc_msg_get_text(). + Text = 10, + + /// Image message. + /// If the image is an animated GIF, the type DC_MSG_GIF should be used. + /// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension + /// and retrieved via dc_msg_set_file(), dc_msg_set_dimension(). + Image = 20, + + /// Animated GIF message. + /// File, width and height are set via dc_msg_set_file(), dc_msg_set_dimension() + /// and retrieved via dc_msg_get_file(), dc_msg_get_width(), dc_msg_get_height(). + Gif = 21, + + /// Message containing an Audio file. + /// File and duration are set via dc_msg_set_file(), dc_msg_set_duration() + /// and retrieved via dc_msg_get_file(), dc_msg_get_duration(). + Audio = 40, + + /// A voice message that was directly recorded by the user. + /// For all other audio messages, the type #DC_MSG_AUDIO should be used. + /// File and duration are set via dc_msg_set_file(), dc_msg_set_duration() + /// and retrieved via dc_msg_get_file(), dc_msg_get_duration() + Voice = 41, + + /// Video messages. + /// File, width, height and durarion + /// are set via dc_msg_set_file(), dc_msg_set_dimension(), dc_msg_set_duration() + /// and retrieved via + /// dc_msg_get_file(), dc_msg_get_width(), + /// dc_msg_get_height(), dc_msg_get_duration(). + Video = 50, + + /// Message containing any file, eg. a PDF. + /// The file is set via dc_msg_set_file() + /// and retrieved via dc_msg_get_file(). + File = 60, +} + +impl ToSql for Viewtype { + fn to_sql(&self) -> sql::Result { + let num: i64 = self + .to_i64() + .expect("impossible: Viewtype -> i64 conversion failed"); + + Ok(ToSqlOutput::Owned(Value::Integer(num))) + } +} + +impl FromSql for Viewtype { + fn column_result(col: ValueRef) -> FromSqlResult { + let inner = FromSql::column_result(col)?; + FromPrimitive::from_i64(inner).ok_or(FromSqlError::InvalidType) + } +} + +impl fmt::Display for Viewtype { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + self.to_i64() + .expect("impossible: Viewtype -> i64 conversion failed") + ) + } +} + // These constants are used as events // reported to the callback given to dc_context_new(). // If you do not want to handle an event, it is always safe to return 0, diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 4166d7db6..03ebd1c03 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -371,14 +371,14 @@ pub unsafe fn dc_prepare_msg<'a>( return msg_id; } -pub fn msgtype_has_file(msgtype: i32) -> bool { +pub fn msgtype_has_file(msgtype: Viewtype) -> bool { match msgtype { - DC_MSG_IMAGE => true, - DC_MSG_GIF => true, - DC_MSG_AUDIO => true, - DC_MSG_VOICE => true, - DC_MSG_VIDEO => true, - DC_MSG_FILE => true, + Viewtype::Image => true, + Viewtype::Gif => true, + Viewtype::Audio => true, + Viewtype::Voice => true, + Viewtype::Video => true, + Viewtype::File => true, _ => false, } } @@ -392,7 +392,7 @@ unsafe fn prepare_msg_common<'a>( let mut OK_TO_CONTINUE = true; (*msg).id = 0i32 as uint32_t; (*msg).context = context; - if (*msg).type_0 == DC_MSG_TEXT { + if (*msg).type_0 == Viewtype::Text { /* the caller should check if the message text is empty */ } else if msgtype_has_file((*msg).type_0) { let mut pathNfilename = (*msg) @@ -417,16 +417,16 @@ unsafe fn prepare_msg_common<'a>( OK_TO_CONTINUE = false; } else { (*msg).param.set(Param::File, as_str(pathNfilename)); - if (*msg).type_0 == DC_MSG_FILE || (*msg).type_0 == DC_MSG_IMAGE { + if (*msg).type_0 == Viewtype::File || (*msg).type_0 == Viewtype::Image { /* Correct the type, take care not to correct already very special formats as GIF or VOICE. Typical conversions: - from FILE to AUDIO/VIDEO/IMAGE - from FILE/IMAGE to GIF */ - let mut better_type = 0; + let mut better_type = Viewtype::Unknown; let mut better_mime = std::ptr::null_mut(); dc_msg_guess_msgtype_from_suffix(pathNfilename, &mut better_type, &mut better_mime); - if 0 != better_type && !better_mime.is_null() { + if Viewtype::Unknown != better_type && !better_mime.is_null() { (*msg).type_0 = better_type; (*msg).param.set(Param::MimeType, as_str(better_mime)); } @@ -436,7 +436,7 @@ unsafe fn prepare_msg_common<'a>( dc_msg_guess_msgtype_from_suffix( pathNfilename, - 0 as *mut libc::c_int, + 0 as *mut Viewtype, &mut better_mime, ); @@ -974,7 +974,7 @@ pub unsafe fn dc_send_text_msg( return 0; } - let mut msg = dc_msg_new(context, 10); + let mut msg = dc_msg_new(context, Viewtype::Text); (*msg).text = dc_strdup(text_to_send); let ret = dc_send_msg(context, chat_id, msg); dc_msg_unref(msg); @@ -1004,7 +1004,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t } // save new draft if !msg.is_null() { - if (*msg).type_0 == DC_MSG_TEXT { + if (*msg).type_0 == Viewtype::Text { if (*msg).text.is_null() || *(*msg).text.offset(0isize) as libc::c_int == 0i32 { OK_TO_CONTINUE = false; } @@ -1258,20 +1258,20 @@ pub fn dc_marknoticed_all_chats(context: &Context) -> bool { pub fn dc_get_chat_media( context: &Context, chat_id: uint32_t, - msg_type: libc::c_int, - msg_type2: libc::c_int, - msg_type3: libc::c_int, + msg_type: Viewtype, + msg_type2: Viewtype, + msg_type3: Viewtype, ) -> *mut dc_array_t { context.sql.query_map( "SELECT id FROM msgs WHERE chat_id=? AND (type=? OR type=? OR type=?) ORDER BY timestamp, id;", params![ chat_id as i32, msg_type, - if msg_type2 > 0 { + if msg_type2 != Viewtype::Unknown { msg_type2 } else { msg_type - }, if msg_type3 > 0 { + }, if msg_type3 != Viewtype::Unknown { msg_type3 } else { msg_type @@ -1292,9 +1292,9 @@ pub unsafe fn dc_get_next_media( context: &Context, curr_msg_id: uint32_t, dir: libc::c_int, - msg_type: libc::c_int, - msg_type2: libc::c_int, - msg_type3: libc::c_int, + msg_type: Viewtype, + msg_type2: Viewtype, + msg_type3: Viewtype, ) -> uint32_t { let mut ret_msg_id: uint32_t = 0i32 as uint32_t; let msg: *mut dc_msg_t = dc_msg_new_untyped(context); @@ -1306,7 +1306,7 @@ pub unsafe fn dc_get_next_media( list = dc_get_chat_media( context, (*msg).chat_id, - if msg_type > 0i32 { + if msg_type != Viewtype::Unknown { msg_type } else { (*msg).type_0 @@ -1510,7 +1510,7 @@ pub unsafe fn dc_create_group_chat( chat_id = sql::get_rowid(context, &context.sql, "chats", "grpid", grpid); if chat_id != 0 { if 0 != dc_add_to_chat_contacts_table(context, chat_id, 1) { - let draft_msg = dc_msg_new(context, 10); + let draft_msg = dc_msg_new(context, Viewtype::Text); dc_msg_set_text(draft_msg, draft_txt.as_ptr()); set_draft_raw(context, chat_id, draft_msg); dc_msg_unref(draft_msg); @@ -1619,7 +1619,7 @@ pub unsafe fn dc_add_contact_to_chat_ex( } if OK_TO_CONTINUE { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { - (*msg).type_0 = DC_MSG_TEXT; + (*msg).type_0 = Viewtype::Text; (*msg).text = to_cstring(context.stock_system_msg( StockMessage::MsgAddMember, as_str((*contact).addr), @@ -1730,7 +1730,7 @@ pub unsafe fn dc_remove_contact_from_chat( /* we should respect this - whatever we send to the group, it gets discarded anyway! */ if !contact.is_null() { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { - (*msg).type_0 = DC_MSG_TEXT; + (*msg).type_0 = Viewtype::Text; if (*contact).id == 1 as libc::c_uint { dc_set_group_explicitly_left(context, (*chat).grpid); (*msg).text = to_cstring(context.stock_system_msg( @@ -1845,7 +1845,7 @@ pub unsafe fn dc_set_chat_name( .is_ok() { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { - (*msg).type_0 = DC_MSG_TEXT; + (*msg).type_0 = Viewtype::Text; (*msg).text = to_cstring(context.stock_system_msg( StockMessage::MsgGrpName, as_str((*chat).name), @@ -1917,7 +1917,7 @@ pub unsafe fn dc_set_chat_profile_image( if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { (*msg).param.set_int(Param::Cmd, 3); (*msg).param.set(Param::Arg, as_str(new_image_rel)); - (*msg).type_0 = DC_MSG_TEXT; + (*msg).type_0 = Viewtype::Text; (*msg).text = to_cstring(context.stock_system_msg( if !new_image_rel.is_null() { StockMessage::MsgGrpImgChanged @@ -2287,7 +2287,7 @@ pub fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *const libc 2, 2, unsafe {dc_create_smeared_timestamp(context)}, - DC_MSG_TEXT, + Viewtype::Text, DC_STATE_IN_NOTICED, as_str(text), as_str(rfc724_mid), diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 4e2618870..cc6ffaf33 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -139,7 +139,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { let chat_id = dc_create_chat_by_contact_id(context, 1i32 as uint32_t); if !(chat_id == 0i32 as libc::c_uint) { msg = dc_msg_new_untyped(context); - (*msg).type_0 = DC_MSG_FILE; + (*msg).type_0 = Viewtype::File; (*msg).param.set(Param::File, as_str(setup_file_name)); (*msg) diff --git a/src/dc_job.rs b/src/dc_job.rs index fe30c4873..78d18f28a 100644 --- a/src/dc_job.rs +++ b/src/dc_job.rs @@ -1184,8 +1184,8 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in .unwrap_or_default(), ); if strlen(pathNfilename) > 0 { - if ((*mimefactory.msg).type_0 == DC_MSG_IMAGE - || (*mimefactory.msg).type_0 == DC_MSG_GIF) + if ((*mimefactory.msg).type_0 == Viewtype::Image + || (*mimefactory.msg).type_0 == Viewtype::Gif) && !(*mimefactory.msg).param.exists(Param::Width) { let mut buf = 0 as *mut libc::c_uchar; diff --git a/src/dc_location.rs b/src/dc_location.rs index b16e3cb74..14edc3767 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -1,6 +1,7 @@ use std::ffi::CString; use crate::constants::Event; +use crate::constants::*; use crate::context::*; use crate::dc_array::*; use crate::dc_chat::*; @@ -98,7 +99,7 @@ pub unsafe fn dc_send_locations_to_chat( .is_ok() { if 0 != seconds && !is_sending_locations_before { - msg = dc_msg_new(context, 10i32); + msg = dc_msg_new(context, Viewtype::Text); (*msg).text = to_cstring(context.stock_system_msg( StockMessage::MsgLocationEnabled, "", @@ -702,7 +703,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu // the easiest way to determine this, is to check for an empty message queue. // (might not be 100%, however, as positions are sent combined later // and dc_set_location() is typically called periodically, this is ok) - let mut msg = dc_msg_new(context, 10); + let mut msg = dc_msg_new(context, Viewtype::Text); (*msg).hidden = 1; (*msg).param.set_int(Param::Cmd, 9); dc_send_msg(context, chat_id as u32, msg); diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index a3cccb129..22214b125 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -738,10 +738,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: } } } - if let Some(grpimage) = grpimage { let mut meta = dc_msg_new_untyped((*factory).context); - (*meta).type_0 = DC_MSG_IMAGE as libc::c_int; + (*meta).type_0 = Viewtype::Image; (*meta).param.set(Param::File, grpimage); let mut filename_as_sent = 0 as *mut libc::c_char; @@ -762,11 +761,11 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: dc_msg_unref(meta); } - if (*msg).type_0 == DC_MSG_VOICE - || (*msg).type_0 == DC_MSG_AUDIO - || (*msg).type_0 == DC_MSG_VIDEO + if (*msg).type_0 == Viewtype::Voice + || (*msg).type_0 == Viewtype::Audio + || (*msg).type_0 == Viewtype::Video { - if (*msg).type_0 == DC_MSG_VOICE { + if (*msg).type_0 == Viewtype::Voice { mailimf_fields_add( imf_fields, mailimf_field_new_custom( @@ -1179,7 +1178,7 @@ unsafe fn build_body_file( let mut filename_encoded = 0 as *mut libc::c_char; if !pathNfilename.is_null() { - if (*msg).type_0 == DC_MSG_VOICE { + if (*msg).type_0 == Viewtype::Voice { let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0); let suffix = if !suffix.is_null() { @@ -1191,9 +1190,9 @@ unsafe fn build_body_file( .format(&format!("voice-message_%Y-%m-%d_%H-%M-%S.{}", suffix)) .to_string(); filename_to_send = to_cstring(res); - } else if (*msg).type_0 == DC_MSG_AUDIO { + } else if (*msg).type_0 == Viewtype::Audio { filename_to_send = dc_get_filename(pathNfilename) - } else if (*msg).type_0 == DC_MSG_IMAGE || (*msg).type_0 == DC_MSG_GIF { + } else if (*msg).type_0 == Viewtype::Image || (*msg).type_0 == Viewtype::Gif { if base_name.is_null() { base_name = b"image\x00" as *const u8 as *const libc::c_char } @@ -1206,7 +1205,7 @@ unsafe fn build_body_file( b"dat\x00" as *const u8 as *const libc::c_char }, ) - } else if (*msg).type_0 == DC_MSG_VIDEO { + } else if (*msg).type_0 == Viewtype::Video { filename_to_send = dc_mprintf( b"video.%s\x00" as *const u8 as *const libc::c_char, if !suffix.is_null() { diff --git a/src/dc_msg.rs b/src/dc_msg.rs index df4ed8bfe..150d389ef 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -25,7 +25,7 @@ pub struct dc_msg_t<'a> { pub to_id: uint32_t, pub chat_id: uint32_t, pub move_state: dc_move_state_t, - pub type_0: libc::c_int, + pub type_0: Viewtype, pub state: libc::c_int, pub hidden: libc::c_int, pub timestamp_sort: i64, @@ -177,15 +177,15 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch } free(p as *mut libc::c_void); - if (*msg).type_0 != DC_MSG_TEXT { + if (*msg).type_0 != Viewtype::Text { ret += "Type: "; match (*msg).type_0 { - DC_MSG_AUDIO => ret += "Audio", - DC_MSG_FILE => ret += "File", - DC_MSG_GIF => ret += "GIF", - DC_MSG_IMAGE => ret += "Image", - DC_MSG_VIDEO => ret += "Video", - DC_MSG_VOICE => ret += "Voice", + Viewtype::Audio => ret += "Audio", + Viewtype::File => ret += "File", + Viewtype::Gif => ret += "GIF", + Viewtype::Image => ret += "Image", + Viewtype::Video => ret += "Video", + Viewtype::Voice => ret += "Voice", _ => ret += &format!("{}", (*msg).type_0), } ret += "\n"; @@ -222,7 +222,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch } pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a> { - dc_msg_new(context, 0i32) + dc_msg_new(context, Viewtype::Unknown) } /* * @@ -235,7 +235,7 @@ pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a> // to check if a mail was sent, use dc_msg_is_sent() // approx. max. length returned by dc_msg_get_text() // approx. max. length returned by dc_get_msg_info() -pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> { +pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: Viewtype) -> *mut dc_msg_t<'a> { let msg = dc_msg_t { magic: 0x11561156, id: 0, @@ -301,7 +301,7 @@ pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char { None => { if let Some(file) = (*msg).param.get(Param::File) { let file_c = to_cstring(file); - dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut libc::c_int, &mut ret); + dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut Viewtype, &mut ret); if ret.is_null() { ret = dc_strdup( b"application/octet-stream\x00" as *const u8 as *const libc::c_char, @@ -323,11 +323,11 @@ pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char { #[allow(non_snake_case)] pub unsafe fn dc_msg_guess_msgtype_from_suffix( pathNfilename: *const libc::c_char, - mut ret_msgtype: *mut libc::c_int, + mut ret_msgtype: *mut Viewtype, mut ret_mime: *mut *mut libc::c_char, ) { let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char; - let mut dummy_msgtype: libc::c_int = 0; + let mut dummy_msgtype = Viewtype::Unknown; let mut dummy_buf: *mut libc::c_char = 0 as *mut libc::c_char; if !pathNfilename.is_null() { if ret_msgtype.is_null() { @@ -336,37 +336,37 @@ pub unsafe fn dc_msg_guess_msgtype_from_suffix( if ret_mime.is_null() { ret_mime = &mut dummy_buf } - *ret_msgtype = 0; + *ret_msgtype = Viewtype::Unknown; *ret_mime = 0 as *mut libc::c_char; suffix = dc_get_filesuffix_lc(pathNfilename); if !suffix.is_null() { if strcmp(suffix, b"mp3\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_AUDIO; + *ret_msgtype = Viewtype::Audio; *ret_mime = dc_strdup(b"audio/mpeg\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"aac\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_AUDIO; + *ret_msgtype = Viewtype::Audio; *ret_mime = dc_strdup(b"audio/aac\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"mp4\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_VIDEO; + *ret_msgtype = Viewtype::Video; *ret_mime = dc_strdup(b"video/mp4\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"jpg\x00" as *const u8 as *const libc::c_char) == 0i32 || strcmp(suffix, b"jpeg\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_IMAGE; + *ret_msgtype = Viewtype::Image; *ret_mime = dc_strdup(b"image/jpeg\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"png\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_IMAGE; + *ret_msgtype = Viewtype::Image; *ret_mime = dc_strdup(b"image/png\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"webp\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_IMAGE; + *ret_msgtype = Viewtype::Image; *ret_mime = dc_strdup(b"image/webp\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"gif\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_GIF; + *ret_msgtype = Viewtype::Gif; *ret_mime = dc_strdup(b"image/gif\x00" as *const u8 as *const libc::c_char) } else if strcmp(suffix, b"vcf\x00" as *const u8 as *const libc::c_char) == 0i32 || strcmp(suffix, b"vcard\x00" as *const u8 as *const libc::c_char) == 0i32 { - *ret_msgtype = DC_MSG_FILE; + *ret_msgtype = Viewtype::File; *ret_mime = dc_strdup(b"text/vcard\x00" as *const u8 as *const libc::c_char) } } @@ -681,9 +681,9 @@ pub unsafe fn dc_msg_get_chat_id(msg: *const dc_msg_t) -> uint32_t { }; } -pub unsafe fn dc_msg_get_viewtype(msg: *const dc_msg_t) -> libc::c_int { +pub unsafe fn dc_msg_get_viewtype(msg: *const dc_msg_t) -> Viewtype { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { - return 0i32; + return Viewtype::Unknown; } (*msg).type_0 @@ -853,7 +853,7 @@ pub unsafe fn dc_msg_get_summarytext( /* the returned value must be free()'d */ #[allow(non_snake_case)] pub unsafe fn dc_msg_get_summarytext_by_raw( - type_0: libc::c_int, + type_0: Viewtype, text: *const libc::c_char, param: &mut Params, approx_characters: libc::c_int, @@ -866,11 +866,11 @@ pub unsafe fn dc_msg_get_summarytext_by_raw( let mut value: *mut libc::c_char = 0 as *mut libc::c_char; let mut append_text: libc::c_int = 1i32; match type_0 { - 20 => prefix = to_cstring(context.stock_str(StockMessage::Image)), - 21 => prefix = to_cstring(context.stock_str(StockMessage::Gif)), - 50 => prefix = to_cstring(context.stock_str(StockMessage::Video)), - 41 => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)), - 40 | 60 => { + Viewtype::Image => prefix = to_cstring(context.stock_str(StockMessage::Image)), + Viewtype::Gif => prefix = to_cstring(context.stock_str(StockMessage::Gif)), + Viewtype::Video => prefix = to_cstring(context.stock_str(StockMessage::Video)), + Viewtype::Voice => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)), + Viewtype::Audio | Viewtype::File => { if param.get_int(Param::Cmd) == Some(6) { prefix = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject)); append_text = 0i32 @@ -879,7 +879,7 @@ pub unsafe fn dc_msg_get_summarytext_by_raw( value = dc_get_filename(pathNfilename); let label = CString::new( context - .stock_str(if type_0 == DC_MSG_AUDIO { + .stock_str(if type_0 == Viewtype::Audio { StockMessage::Audio } else { StockMessage::File @@ -1000,7 +1000,7 @@ pub unsafe fn dc_msg_is_increation(msg: *const dc_msg_t) -> libc::c_int { pub unsafe fn dc_msg_is_setupmessage(msg: *const dc_msg_t) -> bool { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint - || (*msg).type_0 != DC_MSG_FILE as libc::c_int + || (*msg).type_0 != Viewtype::File { return false; } @@ -1442,7 +1442,7 @@ mod tests { #[test] fn test_dc_msg_guess_msgtype_from_suffix() { unsafe { - let mut type_0: libc::c_int = 0; + let mut type_0 = Viewtype::Unknown; let mut mime_0: *mut libc::c_char = 0 as *mut libc::c_char; dc_msg_guess_msgtype_from_suffix( @@ -1450,7 +1450,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_AUDIO as libc::c_int); + assert_eq!(type_0, Viewtype::Audio); assert_eq!(as_str(mime_0 as *const libc::c_char), "audio/mpeg"); free(mime_0 as *mut libc::c_void); @@ -1459,7 +1459,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_AUDIO as libc::c_int); + assert_eq!(type_0, Viewtype::Audio); assert_eq!(as_str(mime_0 as *const libc::c_char), "audio/aac"); free(mime_0 as *mut libc::c_void); @@ -1468,7 +1468,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_VIDEO as libc::c_int); + assert_eq!(type_0, Viewtype::Video); assert_eq!(as_str(mime_0 as *const libc::c_char), "video/mp4"); free(mime_0 as *mut libc::c_void); @@ -1477,7 +1477,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int); + assert_eq!(type_0, Viewtype::Image); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() @@ -1491,7 +1491,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int); + assert_eq!(type_0, Viewtype::Image); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() @@ -1505,7 +1505,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int); + assert_eq!(type_0, Viewtype::Image); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() @@ -1519,7 +1519,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_IMAGE as libc::c_int); + assert_eq!(type_0, Viewtype::Image); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() @@ -1533,7 +1533,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_GIF as libc::c_int); + assert_eq!(type_0, Viewtype::Gif); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() @@ -1547,7 +1547,7 @@ mod tests { &mut type_0, &mut mime_0, ); - assert_eq!(type_0, DC_MSG_FILE as libc::c_int); + assert_eq!(type_0, Viewtype::File); assert_eq!( CStr::from_ptr(mime_0 as *const libc::c_char) .to_str() diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index 3bf1f305b..d1910212d 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -263,7 +263,7 @@ unsafe fn send_handshake_msg( grpid: *const libc::c_char, ) { let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context); - (*msg).type_0 = DC_MSG_TEXT; + (*msg).type_0 = Viewtype::Text; (*msg).text = dc_mprintf( b"Secure-Join: %s\x00" as *const u8 as *const libc::c_char, step,