deltachat/constants.rs
1//! # Constants.
2
3#![allow(missing_docs)]
4
5use std::sync::LazyLock;
6
7use deltachat_derive::{FromSql, ToSql};
8use percent_encoding::{AsciiSet, NON_ALPHANUMERIC};
9use serde::{Deserialize, Serialize};
10
11use crate::chat::ChatId;
12
13pub static DC_VERSION_STR: LazyLock<String> =
14 LazyLock::new(|| env!("CARGO_PKG_VERSION").to_string());
15
16/// Set of characters to percent-encode in email addresses and names.
17pub(crate) const NON_ALPHANUMERIC_WITHOUT_DOT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'.');
18
19#[derive(
20 Debug,
21 Default,
22 Display,
23 Clone,
24 Copy,
25 PartialEq,
26 Eq,
27 FromPrimitive,
28 ToPrimitive,
29 FromSql,
30 ToSql,
31 Serialize,
32 Deserialize,
33)]
34#[repr(i8)]
35pub enum Blocked {
36 #[default]
37 Not = 0,
38 Yes = 1,
39 Request = 2,
40}
41
42#[derive(
43 Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql,
44)]
45#[repr(u8)]
46pub enum ShowEmails {
47 Off = 0,
48 AcceptedContacts = 1,
49 #[default] // also change Config.ShowEmails props(default) on changes
50 All = 2,
51}
52
53#[derive(
54 Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql,
55)]
56#[repr(u8)]
57pub enum MediaQuality {
58 #[default] // also change Config.MediaQuality props(default) on changes
59 Balanced = 0,
60 Worse = 1,
61}
62
63pub const DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING: i32 = 0x01;
64pub const DC_HANDSHAKE_STOP_NORMAL_PROCESSING: i32 = 0x02;
65pub const DC_HANDSHAKE_ADD_DELETE_JOB: i32 = 0x04;
66
67pub(crate) const DC_FROM_HANDSHAKE: i32 = 0x01;
68
69pub const DC_GCL_ARCHIVED_ONLY: usize = 0x01;
70pub const DC_GCL_NO_SPECIALS: usize = 0x02;
71pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
72pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
73
74pub const DC_GCL_ADD_SELF: u32 = 0x02;
75pub const DC_GCL_ADDRESS: u32 = 0x04;
76
77// unchanged user avatars are resent to the recipients every some days
78pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;
79
80// warn about an outdated app after a given number of days.
81// reference is the release date.
82// as not all system get speedy updates,
83// do not use too small value that will annoy users checking for nonexistent updates.
84// "90 days" has proven to be too short at some point (user were informed but there was no update)
85pub(crate) const DC_OUTDATED_WARNING_DAYS: i64 = 183;
86
87/// messages that should be deleted get this chat_id; the messages are deleted from the working thread later then. This is also needed as rfc724_mid should be preset as long as the message is not deleted on the server (otherwise it is downloaded again)
88pub const DC_CHAT_ID_TRASH: ChatId = ChatId::new(3);
89/// only an indicator in a chatlist
90pub const DC_CHAT_ID_ARCHIVED_LINK: ChatId = ChatId::new(6);
91/// only an indicator in a chatlist
92pub const DC_CHAT_ID_ALLDONE_HINT: ChatId = ChatId::new(7);
93/// larger chat IDs are "real" chats, their messages are "real" messages.
94pub const DC_CHAT_ID_LAST_SPECIAL: ChatId = ChatId::new(9);
95
96/// Chat type.
97#[derive(
98 Debug,
99 Display,
100 Clone,
101 Copy,
102 PartialEq,
103 Eq,
104 PartialOrd,
105 Ord,
106 FromPrimitive,
107 ToPrimitive,
108 FromSql,
109 ToSql,
110 IntoStaticStr,
111 Serialize,
112 Deserialize,
113)]
114#[repr(u32)]
115pub enum Chattype {
116 /// A 1:1 chat, i.e. a normal chat with a single contact.
117 ///
118 /// Created by [`ChatId::create_for_contact`].
119 Single = 100,
120
121 /// Group chat.
122 ///
123 /// Created by [`crate::chat::create_group`].
124 Group = 120,
125
126 /// An (unencrypted) mailing list,
127 /// created by an incoming mailing list email.
128 Mailinglist = 140,
129
130 /// Outgoing broadcast channel, called "Channel" in the UI.
131 ///
132 /// The user can send into this chat,
133 /// and all recipients will receive messages
134 /// in an `InBroadcast`.
135 ///
136 /// Called `broadcast` here rather than `channel`,
137 /// because the word "channel" already appears a lot in the code,
138 /// which would make it hard to grep for it.
139 ///
140 /// Created by [`crate::chat::create_broadcast`].
141 OutBroadcast = 160,
142
143 /// Incoming broadcast channel, called "Channel" in the UI.
144 ///
145 /// This chat is read-only,
146 /// and we do not know who the other recipients are.
147 ///
148 /// This is similar to a `MailingList`,
149 /// with the main difference being that
150 /// `InBroadcast`s are encrypted.
151 ///
152 /// Called `broadcast` here rather than `channel`,
153 /// because the word "channel" already appears a lot in the code,
154 /// which would make it hard to grep for it.
155 InBroadcast = 165,
156}
157
158pub const DC_MSG_ID_DAYMARKER: u32 = 9;
159pub const DC_MSG_ID_LAST_SPECIAL: u32 = 9;
160
161/// String that indicates that something is left out or truncated.
162pub(crate) const DC_ELLIPSIS: &str = "[...]";
163// how many lines desktop can display when fullscreen (fullscreen at zoomlevel 1x)
164// (taken from "subjective" testing what looks ok)
165pub const DC_DESIRED_TEXT_LINES: usize = 38;
166// how many chars desktop can display per line (from "subjective" testing)
167pub const DC_DESIRED_TEXT_LINE_LEN: usize = 100;
168
169/// Message length limit.
170///
171/// To keep bubbles and chat flow usable and to avoid problems with controls using very long texts,
172/// we limit the text length to `DC_DESIRED_TEXT_LEN`. If the text is longer, the full text can be
173/// retrieved using has_html()/get_html().
174///
175/// Note that for simplicity maximum length is defined as the number of Unicode Scalar Values (Rust
176/// `char`s), not Unicode Grapheme Clusters.
177pub const DC_DESIRED_TEXT_LEN: usize = DC_DESIRED_TEXT_LINE_LEN * DC_DESIRED_TEXT_LINES;
178
179// Flags for configuring IMAP and SMTP servers.
180// These flags are optional
181// and may be set together with the username, password etc.
182// via dc_set_config() using the key "server_flags".
183
184/// Force OAuth2 authorization.
185///
186/// This flag does not skip automatic configuration.
187/// Before calling configure() with DC_LP_AUTH_OAUTH2 set,
188/// the user has to confirm access at the URL returned by dc_get_oauth2_url().
189pub const DC_LP_AUTH_OAUTH2: i32 = 0x2;
190
191/// Force NORMAL authorization, this is the default.
192/// If this flag is set, automatic configuration is skipped.
193pub const DC_LP_AUTH_NORMAL: i32 = 0x4;
194
195/// if none of these flags are set, the default is chosen
196pub const DC_LP_AUTH_FLAGS: i32 = DC_LP_AUTH_OAUTH2 | DC_LP_AUTH_NORMAL;
197
198// max. weight of images to send w/o recoding
199pub const BALANCED_IMAGE_BYTES: usize = 500_000;
200pub const WORSE_IMAGE_BYTES: usize = 130_000;
201
202// max. width/height and bytes of an avatar
203pub(crate) const BALANCED_AVATAR_SIZE: u32 = 512;
204pub(crate) const BALANCED_AVATAR_BYTES: usize = 60_000;
205pub(crate) const WORSE_AVATAR_SIZE: u32 = 128;
206pub(crate) const WORSE_AVATAR_BYTES: usize = 20_000; // this also fits to Outlook servers don't allowing headers larger than 32k.
207
208// max. width/height of images scaled down because of being too huge
209pub const BALANCED_IMAGE_SIZE: u32 = 1280;
210pub const WORSE_IMAGE_SIZE: u32 = 640;
211
212/// Limit for received images size. Bigger images become `Viewtype::File` to avoid excessive memory
213/// usage by UIs.
214pub const MAX_RCVD_IMAGE_PIXELS: u32 = 50_000_000;
215
216// Key for the folder configuration version (see below).
217pub(crate) const DC_FOLDERS_CONFIGURED_KEY: &str = "folders_configured";
218// this value can be increased if the folder configuration is changed and must be redone on next program start
219pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 5;
220
221// If more recipients are needed in SMTP's `RCPT TO:` header, the recipient list is split into
222// chunks. This does not affect MIME's `To:` header. Can be overwritten by setting
223// `max_smtp_rcpt_to` in the provider db.
224pub(crate) const DEFAULT_MAX_SMTP_RCPT_TO: usize = 50;
225
226/// How far the last quota check needs to be in the past to be checked by the background function (in seconds).
227pub(crate) const DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT: u64 = 12 * 60 * 60; // 12 hours
228
229/// How far in the future the sender timestamp of a message is allowed to be, in seconds. Also used
230/// in the group membership consistency algo to reject outdated membership changes.
231pub(crate) const TIMESTAMP_SENT_TOLERANCE: i64 = 60;
232
233// To make text edits clearer for Non-Delta-MUA or old Delta Chats, edited text will be prefixed by EDITED_PREFIX.
234// Newer Delta Chats will remove the prefix as needed.
235pub(crate) const EDITED_PREFIX: &str = "✏️";
236
237// Strings needed to render the Autocrypt Setup Message.
238// Left untranslated as not being supported/recommended workflow and as translations would require deep knowledge.
239pub(crate) const ASM_SUBJECT: &str = "Autocrypt Setup Message";
240pub(crate) const ASM_BODY: &str = "This is the Autocrypt Setup Message \
241 used to transfer your end-to-end setup between clients.
242
243 To decrypt and use your setup, \
244 open the message in an Autocrypt-compliant client \
245 and enter the setup code presented on the generating device.
246
247 If you see this message in a chatmail client (Delta Chat, Arcane Chat, Delta Touch ...), \
248 use \"Settings / Add Second Device\" instead.";
249
250/// Period between `sql::housekeeping()` runs.
251pub(crate) const HOUSEKEEPING_PERIOD: i64 = 24 * 60 * 60;
252
253#[cfg(test)]
254mod tests {
255 use num_traits::FromPrimitive;
256
257 use super::*;
258
259 #[test]
260 fn test_chattype_values() {
261 // values may be written to disk and must not change
262 assert_eq!(Chattype::Single, Chattype::from_i32(100).unwrap());
263 assert_eq!(Chattype::Group, Chattype::from_i32(120).unwrap());
264 assert_eq!(Chattype::Mailinglist, Chattype::from_i32(140).unwrap());
265 assert_eq!(Chattype::OutBroadcast, Chattype::from_i32(160).unwrap());
266 }
267
268 #[test]
269 fn test_showemails_values() {
270 // values may be written to disk and must not change
271 assert_eq!(ShowEmails::All, ShowEmails::default());
272 assert_eq!(ShowEmails::Off, ShowEmails::from_i32(0).unwrap());
273 assert_eq!(
274 ShowEmails::AcceptedContacts,
275 ShowEmails::from_i32(1).unwrap()
276 );
277 assert_eq!(ShowEmails::All, ShowEmails::from_i32(2).unwrap());
278 }
279
280 #[test]
281 fn test_blocked_values() {
282 // values may be written to disk and must not change
283 assert_eq!(Blocked::Not, Blocked::default());
284 assert_eq!(Blocked::Not, Blocked::from_i32(0).unwrap());
285 assert_eq!(Blocked::Yes, Blocked::from_i32(1).unwrap());
286 assert_eq!(Blocked::Request, Blocked::from_i32(2).unwrap());
287 }
288
289 #[test]
290 fn test_mediaquality_values() {
291 // values may be written to disk and must not change
292 assert_eq!(MediaQuality::Balanced, MediaQuality::default());
293 assert_eq!(MediaQuality::Balanced, MediaQuality::from_i32(0).unwrap());
294 assert_eq!(MediaQuality::Worse, MediaQuality::from_i32(1).unwrap());
295 }
296}