mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
refactor: remove unused functions from the tools module
Also marked functions that are not used outside as pub(crate). Some functions like get_filesuffix_lc() are still used by deltachat-repl, so the whole module cannot be made private.
This commit is contained in:
88
src/tools.rs
88
src/tools.rs
@@ -24,16 +24,13 @@ pub use std::time::SystemTime;
|
|||||||
use anyhow::{Context as _, Result, bail, ensure};
|
use anyhow::{Context as _, Result, bail, ensure};
|
||||||
use base64::Engine as _;
|
use base64::Engine as _;
|
||||||
use chrono::{Local, NaiveDateTime, NaiveTime, TimeZone};
|
use chrono::{Local, NaiveDateTime, NaiveTime, TimeZone};
|
||||||
use deltachat_contact_tools::EmailAddress;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use deltachat_time::SystemTimeTools as SystemTime;
|
pub use deltachat_time::SystemTimeTools as SystemTime;
|
||||||
use futures::TryStreamExt;
|
|
||||||
use mailparse::MailHeaderMap;
|
use mailparse::MailHeaderMap;
|
||||||
use mailparse::dateparse;
|
use mailparse::dateparse;
|
||||||
use mailparse::headers::Headers;
|
use mailparse::headers::Headers;
|
||||||
use num_traits::PrimInt;
|
use num_traits::PrimInt;
|
||||||
use tokio::{fs, io};
|
use tokio::{fs, io};
|
||||||
use url::Url;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::chat::{add_device_msg, add_device_msg_with_importance};
|
use crate::chat::{add_device_msg, add_device_msg_with_importance};
|
||||||
@@ -165,7 +162,7 @@ pub fn timestamp_to_str(wanted: i64) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts duration to string representation suitable for logs.
|
/// Converts duration to string representation suitable for logs.
|
||||||
pub fn duration_to_str(duration: Duration) -> String {
|
pub(crate) fn duration_to_str(duration: Duration) -> String {
|
||||||
let secs = duration.as_secs();
|
let secs = duration.as_secs();
|
||||||
let h = secs / 3600;
|
let h = secs / 3600;
|
||||||
let m = (secs % 3600) / 60;
|
let m = (secs % 3600) / 60;
|
||||||
@@ -182,7 +179,7 @@ pub(crate) fn gm2local_offset() -> i64 {
|
|||||||
|
|
||||||
/// Returns the last release timestamp as a unix timestamp compatible for comparison with time() and
|
/// Returns the last release timestamp as a unix timestamp compatible for comparison with time() and
|
||||||
/// database times.
|
/// database times.
|
||||||
pub fn get_release_timestamp() -> i64 {
|
pub(crate) fn get_release_timestamp() -> i64 {
|
||||||
NaiveDateTime::new(
|
NaiveDateTime::new(
|
||||||
*crate::release::DATE,
|
*crate::release::DATE,
|
||||||
NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
|
NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
|
||||||
@@ -498,48 +495,6 @@ pub async fn read_file(context: &Context, path: &Path) -> Result<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn open_file(context: &Context, path: &Path) -> Result<fs::File> {
|
|
||||||
let path_abs = get_abs_path(context, path);
|
|
||||||
|
|
||||||
match fs::File::open(&path_abs).await {
|
|
||||||
Ok(bytes) => Ok(bytes),
|
|
||||||
Err(err) => {
|
|
||||||
warn!(
|
|
||||||
context,
|
|
||||||
"Cannot read \"{}\" or file is empty: {}",
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
);
|
|
||||||
Err(err.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn open_file_std(context: &Context, path: impl AsRef<Path>) -> Result<std::fs::File> {
|
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
|
||||||
|
|
||||||
match std::fs::File::open(path_abs) {
|
|
||||||
Ok(bytes) => Ok(bytes),
|
|
||||||
Err(err) => {
|
|
||||||
warn!(
|
|
||||||
context,
|
|
||||||
"Cannot read \"{}\" or file is empty: {}",
|
|
||||||
path.as_ref().display(),
|
|
||||||
err
|
|
||||||
);
|
|
||||||
Err(err.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads directory and returns a vector of directory entries.
|
|
||||||
pub async fn read_dir(path: &Path) -> Result<Vec<fs::DirEntry>> {
|
|
||||||
let res = tokio_stream::wrappers::ReadDirStream::new(fs::read_dir(path).await?)
|
|
||||||
.try_collect()
|
|
||||||
.await?;
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn time() -> i64 {
|
pub(crate) fn time() -> i64 {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
@@ -551,43 +506,6 @@ pub(crate) fn time_elapsed(time: &Time) -> Duration {
|
|||||||
time.elapsed().unwrap_or_default()
|
time.elapsed().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct containing all mailto information
|
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
|
||||||
pub struct MailTo {
|
|
||||||
pub to: Vec<EmailAddress>,
|
|
||||||
pub subject: Option<String>,
|
|
||||||
pub body: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse mailto urls
|
|
||||||
pub fn parse_mailto(mailto_url: &str) -> Option<MailTo> {
|
|
||||||
if let Ok(url) = Url::parse(mailto_url) {
|
|
||||||
if url.scheme() == "mailto" {
|
|
||||||
let mut mailto: MailTo = Default::default();
|
|
||||||
// Extract the email address
|
|
||||||
url.path().split(',').for_each(|email| {
|
|
||||||
if let Ok(email) = EmailAddress::new(email) {
|
|
||||||
mailto.to.push(email);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Extract query parameters
|
|
||||||
for (key, value) in url.query_pairs() {
|
|
||||||
if key == "subject" {
|
|
||||||
mailto.subject = Some(value.to_string());
|
|
||||||
} else if key == "body" {
|
|
||||||
mailto.body = Some(value.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(mailto)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) trait IsNoneOrEmpty<T> {
|
pub(crate) trait IsNoneOrEmpty<T> {
|
||||||
/// Returns true if an Option does not contain a string
|
/// Returns true if an Option does not contain a string
|
||||||
/// or contains an empty string.
|
/// or contains an empty string.
|
||||||
@@ -629,7 +547,7 @@ impl ToOption<String> for Option<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::arithmetic_side_effects)]
|
#[expect(clippy::arithmetic_side_effects)]
|
||||||
pub fn remove_subject_prefix(last_subject: &str) -> String {
|
pub(crate) fn remove_subject_prefix(last_subject: &str) -> String {
|
||||||
let subject_start = if last_subject.starts_with("Chat:") {
|
let subject_start = if last_subject.starts_with("Chat:") {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -527,57 +527,6 @@ fn test_remove_subject_prefix() {
|
|||||||
assert_eq!(remove_subject_prefix("Fw: Subject"), "Subject");
|
assert_eq!(remove_subject_prefix("Fw: Subject"), "Subject");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_mailto() {
|
|
||||||
let mailto_url = "mailto:someone@example.com";
|
|
||||||
let reps = parse_mailto(mailto_url);
|
|
||||||
assert_eq!(
|
|
||||||
Some(MailTo {
|
|
||||||
to: vec![EmailAddress {
|
|
||||||
local: "someone".to_string(),
|
|
||||||
domain: "example.com".to_string()
|
|
||||||
}],
|
|
||||||
subject: None,
|
|
||||||
body: None
|
|
||||||
}),
|
|
||||||
reps
|
|
||||||
);
|
|
||||||
|
|
||||||
let mailto_url = "mailto:someone@example.com?subject=Hello%20World";
|
|
||||||
let reps = parse_mailto(mailto_url);
|
|
||||||
assert_eq!(
|
|
||||||
Some(MailTo {
|
|
||||||
to: vec![EmailAddress {
|
|
||||||
local: "someone".to_string(),
|
|
||||||
domain: "example.com".to_string()
|
|
||||||
}],
|
|
||||||
subject: Some("Hello World".to_string()),
|
|
||||||
body: None
|
|
||||||
}),
|
|
||||||
reps
|
|
||||||
);
|
|
||||||
|
|
||||||
let mailto_url = "mailto:someone@example.com,someoneelse@example.com?subject=Hello%20World&body=This%20is%20a%20test";
|
|
||||||
let reps = parse_mailto(mailto_url);
|
|
||||||
assert_eq!(
|
|
||||||
Some(MailTo {
|
|
||||||
to: vec![
|
|
||||||
EmailAddress {
|
|
||||||
local: "someone".to_string(),
|
|
||||||
domain: "example.com".to_string()
|
|
||||||
},
|
|
||||||
EmailAddress {
|
|
||||||
local: "someoneelse".to_string(),
|
|
||||||
domain: "example.com".to_string()
|
|
||||||
}
|
|
||||||
],
|
|
||||||
subject: Some("Hello World".to_string()),
|
|
||||||
body: Some("This is a test".to_string())
|
|
||||||
}),
|
|
||||||
reps
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sanitize_filename() {
|
fn test_sanitize_filename() {
|
||||||
let name = sanitize_filename("Я ЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯ.txt");
|
let name = sanitize_filename("Я ЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯ.txt");
|
||||||
|
|||||||
Reference in New Issue
Block a user