mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
refactor: Don't use traits where it's not necessary (#6567)
Traits are bad for readability and compile times.
This commit is contained in:
@@ -92,7 +92,7 @@ async fn reset_tables(context: &Context, bits: i32) {
|
|||||||
context.emit_msgs_changed_without_ids();
|
context.emit_msgs_changed_without_ids();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn poke_eml_file(context: &Context, filename: impl AsRef<Path>) -> Result<()> {
|
async fn poke_eml_file(context: &Context, filename: &Path) -> Result<()> {
|
||||||
let data = read_file(context, filename).await?;
|
let data = read_file(context, filename).await?;
|
||||||
|
|
||||||
if let Err(err) = receive_imf(context, &data, false).await {
|
if let Err(err) = receive_imf(context, &data, false).await {
|
||||||
@@ -126,7 +126,7 @@ async fn poke_spec(context: &Context, spec: Option<&str>) -> bool {
|
|||||||
real_spec = rs.unwrap();
|
real_spec = rs.unwrap();
|
||||||
}
|
}
|
||||||
if let Some(suffix) = get_filesuffix_lc(&real_spec) {
|
if let Some(suffix) = get_filesuffix_lc(&real_spec) {
|
||||||
if suffix == "eml" && poke_eml_file(context, &real_spec).await.is_ok() {
|
if suffix == "eml" && poke_eml_file(context, Path::new(&real_spec)).await.is_ok() {
|
||||||
read_cnt += 1
|
read_cnt += 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -140,7 +140,10 @@ async fn poke_spec(context: &Context, spec: Option<&str>) -> bool {
|
|||||||
if name.ends_with(".eml") {
|
if name.ends_with(".eml") {
|
||||||
let path_plus_name = format!("{}/{}", &real_spec, name);
|
let path_plus_name = format!("{}/{}", &real_spec, name);
|
||||||
println!("Import: {path_plus_name}");
|
println!("Import: {path_plus_name}");
|
||||||
if poke_eml_file(context, path_plus_name).await.is_ok() {
|
if poke_eml_file(context, Path::new(&path_plus_name))
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
read_cnt += 1
|
read_cnt += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1278,7 +1281,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
"fileinfo" => {
|
"fileinfo" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <file> missing.");
|
ensure!(!arg1.is_empty(), "Argument <file> missing.");
|
||||||
|
|
||||||
if let Ok(buf) = read_file(&context, &arg1).await {
|
if let Ok(buf) = read_file(&context, Path::new(arg1)).await {
|
||||||
let (width, height) = get_filemeta(&buf)?;
|
let (width, height) = get_filemeta(&buf)?;
|
||||||
println!("width={width}, height={height}");
|
println!("width={width}, height={height}");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
21
src/blob.rs
21
src/blob.rs
@@ -1,7 +1,6 @@
|
|||||||
//! # Blob directory management.
|
//! # Blob directory management.
|
||||||
|
|
||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::io::{Cursor, Seek};
|
use std::io::{Cursor, Seek};
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -151,10 +150,10 @@ impl<'a> BlobObject<'a> {
|
|||||||
let rel_path = path
|
let rel_path = path
|
||||||
.strip_prefix(context.get_blobdir())
|
.strip_prefix(context.get_blobdir())
|
||||||
.with_context(|| format!("wrong blobdir: {}", path.display()))?;
|
.with_context(|| format!("wrong blobdir: {}", path.display()))?;
|
||||||
if !BlobObject::is_acceptible_blob_name(rel_path) {
|
let name = rel_path.to_str().context("wrong name")?;
|
||||||
|
if !BlobObject::is_acceptible_blob_name(name) {
|
||||||
return Err(format_err!("bad blob name: {}", rel_path.display()));
|
return Err(format_err!("bad blob name: {}", rel_path.display()));
|
||||||
}
|
}
|
||||||
let name = rel_path.to_str().context("wrong name")?;
|
|
||||||
BlobObject::from_name(context, name)
|
BlobObject::from_name(context, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,19 +215,17 @@ impl<'a> BlobObject<'a> {
|
|||||||
///
|
///
|
||||||
/// This is slightly less strict than stanitise_name, presumably
|
/// This is slightly less strict than stanitise_name, presumably
|
||||||
/// someone already created a file with such a name so we just
|
/// someone already created a file with such a name so we just
|
||||||
/// ensure it's not actually a path in disguise is actually utf-8.
|
/// ensure it's not actually a path in disguise.
|
||||||
fn is_acceptible_blob_name(name: impl AsRef<OsStr>) -> bool {
|
///
|
||||||
let uname = match name.as_ref().to_str() {
|
/// Acceptible blob name always have to be valid utf-8.
|
||||||
Some(name) => name,
|
fn is_acceptible_blob_name(name: &str) -> bool {
|
||||||
None => return false,
|
if name.find('/').is_some() {
|
||||||
};
|
|
||||||
if uname.find('/').is_some() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if uname.find('\\').is_some() {
|
if name.find('\\').is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if uname.find('\0').is_some() {
|
if name.find('\0').is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ async fn test_create_from_name_long() {
|
|||||||
fn test_is_blob_name() {
|
fn test_is_blob_name() {
|
||||||
assert!(BlobObject::is_acceptible_blob_name("foo"));
|
assert!(BlobObject::is_acceptible_blob_name("foo"));
|
||||||
assert!(BlobObject::is_acceptible_blob_name("foo.txt"));
|
assert!(BlobObject::is_acceptible_blob_name("foo.txt"));
|
||||||
assert!(BlobObject::is_acceptible_blob_name("f".repeat(128)));
|
assert!(BlobObject::is_acceptible_blob_name(&"f".repeat(128)));
|
||||||
assert!(!BlobObject::is_acceptible_blob_name("foo/bar"));
|
assert!(!BlobObject::is_acceptible_blob_name("foo/bar"));
|
||||||
assert!(!BlobObject::is_acceptible_blob_name("foo\\bar"));
|
assert!(!BlobObject::is_acceptible_blob_name("foo\\bar"));
|
||||||
assert!(!BlobObject::is_acceptible_blob_name("foo\x00bar"));
|
assert!(!BlobObject::is_acceptible_blob_name("foo\x00bar"));
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ async fn imex_inner(
|
|||||||
.await
|
.await
|
||||||
.context("Cannot create private key or private key not available")?;
|
.context("Cannot create private key or private key not available")?;
|
||||||
|
|
||||||
create_folder(context, &path).await?;
|
create_folder(context, path).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match what {
|
match what {
|
||||||
@@ -600,7 +600,7 @@ where
|
|||||||
|
|
||||||
/// Imports secret key from a file.
|
/// Imports secret key from a file.
|
||||||
async fn import_secret_key(context: &Context, path: &Path, set_default: bool) -> Result<()> {
|
async fn import_secret_key(context: &Context, path: &Path, set_default: bool) -> Result<()> {
|
||||||
let buf = read_file(context, &path).await?;
|
let buf = read_file(context, path).await?;
|
||||||
let armored = std::string::String::from_utf8_lossy(&buf);
|
let armored = std::string::String::from_utf8_lossy(&buf);
|
||||||
set_self_key(context, &armored, set_default).await?;
|
set_self_key(context, &armored, set_default).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -973,7 +973,7 @@ impl Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(filename) = self.get_file(context) {
|
if let Some(filename) = self.get_file(context) {
|
||||||
if let Ok(ref buf) = read_file(context, filename).await {
|
if let Ok(ref buf) = read_file(context, &filename).await {
|
||||||
if let Ok((typ, headers, _)) = split_armored_data(buf) {
|
if let Ok((typ, headers, _)) = split_armored_data(buf) {
|
||||||
if typ == pgp::armor::BlockType::Message {
|
if typ == pgp::armor::BlockType::Message {
|
||||||
return headers.get(crate::pgp::HEADER_SETUPCODE).cloned();
|
return headers.get(crate::pgp::HEADER_SETUPCODE).cloned();
|
||||||
|
|||||||
@@ -400,11 +400,11 @@ impl TestContext {
|
|||||||
/// Sets a name for this [`TestContext`] if one isn't yet set.
|
/// Sets a name for this [`TestContext`] if one isn't yet set.
|
||||||
///
|
///
|
||||||
/// This will show up in events logged in the test output.
|
/// This will show up in events logged in the test output.
|
||||||
pub fn set_name(&self, name: impl Into<String>) {
|
pub fn set_name(&self, name: &str) {
|
||||||
let mut context_names = CONTEXT_NAMES.write().unwrap();
|
let mut context_names = CONTEXT_NAMES.write().unwrap();
|
||||||
context_names
|
context_names
|
||||||
.entry(self.ctx.get_id())
|
.entry(self.ctx.get_id())
|
||||||
.or_insert_with(|| name.into());
|
.or_insert_with(|| name.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the name of this [`TestContext`].
|
/// Returns the name of this [`TestContext`].
|
||||||
|
|||||||
34
src/tools.rs
34
src/tools.rs
@@ -348,14 +348,13 @@ pub(crate) fn get_abs_path(context: &Context, path: &Path) -> PathBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_filebytes(context: &Context, path: impl AsRef<Path>) -> Result<u64> {
|
pub(crate) async fn get_filebytes(context: &Context, path: &Path) -> Result<u64> {
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
let path_abs = get_abs_path(context, path);
|
||||||
let meta = fs::metadata(&path_abs).await?;
|
let meta = fs::metadata(&path_abs).await?;
|
||||||
Ok(meta.len())
|
Ok(meta.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_file(context: &Context, path: impl AsRef<Path>) -> Result<()> {
|
pub(crate) async fn delete_file(context: &Context, path: &Path) -> Result<()> {
|
||||||
let path = path.as_ref();
|
|
||||||
let path_abs = get_abs_path(context, path);
|
let path_abs = get_abs_path(context, path);
|
||||||
if !path_abs.exists() {
|
if !path_abs.exists() {
|
||||||
bail!("path {} does not exist", path_abs.display());
|
bail!("path {} does not exist", path_abs.display());
|
||||||
@@ -443,11 +442,8 @@ impl AsRef<Path> for TempPathGuard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn create_folder(
|
pub(crate) async fn create_folder(context: &Context, path: &Path) -> Result<(), io::Error> {
|
||||||
context: &Context,
|
let path_abs = get_abs_path(context, path);
|
||||||
path: impl AsRef<Path>,
|
|
||||||
) -> Result<(), io::Error> {
|
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
|
||||||
if !path_abs.exists() {
|
if !path_abs.exists() {
|
||||||
match fs::create_dir_all(path_abs).await {
|
match fs::create_dir_all(path_abs).await {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
@@ -455,7 +451,7 @@ pub(crate) async fn create_folder(
|
|||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot create directory \"{}\": {}",
|
"Cannot create directory \"{}\": {}",
|
||||||
path.as_ref().display(),
|
path.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
Err(err)
|
Err(err)
|
||||||
@@ -469,16 +465,16 @@ pub(crate) async fn create_folder(
|
|||||||
/// Write a the given content to provided file path.
|
/// Write a the given content to provided file path.
|
||||||
pub(crate) async fn write_file(
|
pub(crate) async fn write_file(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
path: impl AsRef<Path>,
|
path: &Path,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
let path_abs = get_abs_path(context, path);
|
||||||
fs::write(&path_abs, buf).await.map_err(|err| {
|
fs::write(&path_abs, buf).await.map_err(|err| {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot write {} bytes to \"{}\": {}",
|
"Cannot write {} bytes to \"{}\": {}",
|
||||||
buf.len(),
|
buf.len(),
|
||||||
path.as_ref().display(),
|
path.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
@@ -486,8 +482,8 @@ pub(crate) async fn write_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the file and returns its context as a byte vector.
|
/// Reads the file and returns its context as a byte vector.
|
||||||
pub async fn read_file(context: &Context, path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
pub async fn read_file(context: &Context, path: &Path) -> Result<Vec<u8>> {
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
let path_abs = get_abs_path(context, path);
|
||||||
|
|
||||||
match fs::read(&path_abs).await {
|
match fs::read(&path_abs).await {
|
||||||
Ok(bytes) => Ok(bytes),
|
Ok(bytes) => Ok(bytes),
|
||||||
@@ -495,7 +491,7 @@ pub async fn read_file(context: &Context, path: impl AsRef<Path>) -> Result<Vec<
|
|||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot read \"{}\" or file is empty: {}",
|
"Cannot read \"{}\" or file is empty: {}",
|
||||||
path.as_ref().display(),
|
path.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
Err(err.into())
|
Err(err.into())
|
||||||
@@ -503,8 +499,8 @@ pub async fn read_file(context: &Context, path: impl AsRef<Path>) -> Result<Vec<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn open_file(context: &Context, path: impl AsRef<Path>) -> Result<fs::File> {
|
pub async fn open_file(context: &Context, path: &Path) -> Result<fs::File> {
|
||||||
let path_abs = get_abs_path(context, path.as_ref());
|
let path_abs = get_abs_path(context, path);
|
||||||
|
|
||||||
match fs::File::open(&path_abs).await {
|
match fs::File::open(&path_abs).await {
|
||||||
Ok(bytes) => Ok(bytes),
|
Ok(bytes) => Ok(bytes),
|
||||||
@@ -512,7 +508,7 @@ pub async fn open_file(context: &Context, path: impl AsRef<Path>) -> Result<fs::
|
|||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot read \"{}\" or file is empty: {}",
|
"Cannot read \"{}\" or file is empty: {}",
|
||||||
path.as_ref().display(),
|
path.display(),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
Err(err.into())
|
Err(err.into())
|
||||||
|
|||||||
@@ -282,15 +282,22 @@ async fn test_file_handling() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(delete_file(context, "$BLOBDIR/lkqwjelqkwlje")
|
assert!(delete_file(context, Path::new("$BLOBDIR/lkqwjelqkwlje"))
|
||||||
.await
|
.await
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(write_file(context, "$BLOBDIR/foobar", b"content")
|
assert!(
|
||||||
.await
|
write_file(context, Path::new("$BLOBDIR/foobar"), b"content")
|
||||||
.is_ok());
|
.await
|
||||||
|
.is_ok()
|
||||||
|
);
|
||||||
assert!(file_exist!(context, "$BLOBDIR/foobar"));
|
assert!(file_exist!(context, "$BLOBDIR/foobar"));
|
||||||
assert!(!file_exist!(context, "$BLOBDIR/foobarx"));
|
assert!(!file_exist!(context, "$BLOBDIR/foobarx"));
|
||||||
assert_eq!(get_filebytes(context, "$BLOBDIR/foobar").await.unwrap(), 7);
|
assert_eq!(
|
||||||
|
get_filebytes(context, Path::new("$BLOBDIR/foobar"))
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
7
|
||||||
|
);
|
||||||
|
|
||||||
let abs_path = context
|
let abs_path = context
|
||||||
.get_blobdir()
|
.get_blobdir()
|
||||||
@@ -300,19 +307,23 @@ async fn test_file_handling() {
|
|||||||
|
|
||||||
assert!(file_exist!(context, &abs_path));
|
assert!(file_exist!(context, &abs_path));
|
||||||
|
|
||||||
assert!(delete_file(context, "$BLOBDIR/foobar").await.is_ok());
|
assert!(delete_file(context, Path::new("$BLOBDIR/foobar"))
|
||||||
assert!(create_folder(context, "$BLOBDIR/foobar-folder")
|
.await
|
||||||
|
.is_ok());
|
||||||
|
assert!(create_folder(context, Path::new("$BLOBDIR/foobar-folder"))
|
||||||
.await
|
.await
|
||||||
.is_ok());
|
.is_ok());
|
||||||
assert!(file_exist!(context, "$BLOBDIR/foobar-folder"));
|
assert!(file_exist!(context, "$BLOBDIR/foobar-folder"));
|
||||||
assert!(delete_file(context, "$BLOBDIR/foobar-folder")
|
assert!(delete_file(context, Path::new("$BLOBDIR/foobar-folder"))
|
||||||
.await
|
.await
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
let fn0 = "$BLOBDIR/data.data";
|
let fn0 = "$BLOBDIR/data.data";
|
||||||
assert!(write_file(context, &fn0, b"content").await.is_ok());
|
assert!(write_file(context, Path::new(fn0), b"content")
|
||||||
|
.await
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
assert!(delete_file(context, &fn0).await.is_ok());
|
assert!(delete_file(context, Path::new(fn0)).await.is_ok());
|
||||||
assert!(!file_exist!(context, &fn0));
|
assert!(!file_exist!(context, &fn0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user