v0.0.5
RustBox CI / rustbox (push) Canceled after 0s

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-30 12:06:44 +01:00
1 parent 96a32ea8fb
commit a643e7e3ab
106 files changed
+2223 -4669

No files matched your search

-30
View File
@@ -12,10 +12,6 @@ use crate::error::AppError;
use crate::imap::client::{ImapClient, ImapCredentials};
use crate::search::engine::SearchEngine;
// ---------------------------------------------------------------------------
// Request / Response types
// ---------------------------------------------------------------------------
#[derive(Deserialize)]
pub struct CreateFolderRequest {
pub name: String,
@@ -36,19 +32,12 @@ struct MessageResponse {
status: &'static str,
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/// Folder names that must not be renamed or deleted.
const SYSTEM_FOLDERS: &[&str] = &["INBOX", "Sent", "Drafts", "Trash", "Junk", "Spam"];
/// Returns `true` if the folder is a system folder (case-insensitive).
fn is_system_folder(name: &str) -> bool {
SYSTEM_FOLDERS.iter().any(|s| s.eq_ignore_ascii_case(name))
}
/// Validates a folder name. Returns `Ok(())` if valid, or an `AppError::BadRequest`.
fn validate_folder_name(name: &str) -> Result<(), AppError> {
if name.trim().is_empty() {
return Err(AppError::BadRequest(
@@ -73,7 +62,6 @@ fn validate_folder_name(name: &str) -> Result<(), AppError> {
Ok(())
}
/// Build IMAP credentials from the session and app configuration.
fn build_creds(session: &SessionState, _config: &AppConfig) -> Result<ImapCredentials, AppError> {
Ok(ImapCredentials {
host: session.imap_host.clone(),
@@ -85,11 +73,6 @@ fn build_creds(session: &SessionState, _config: &AppConfig) -> Result<ImapCreden
})
}
// ---------------------------------------------------------------------------
// Handlers
// ---------------------------------------------------------------------------
/// `POST /api/folders` -- create a new IMAP folder.
pub async fn create_folder(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -100,13 +83,11 @@ pub async fn create_folder(
let creds = build_creds(&session, &config)?;
// Create the folder on the IMAP server (also subscribes).
imap_client
.create_folder(&creds, &body.name)
.await
.map_err(|e| AppError::InternalError(format!("IMAP create_folder failed: {e}")))?;
// Cache the new folder locally.
let conn = db::pool::open_user_db(&config.data_dir, &session.user_hash)
.map_err(|e| AppError::InternalError(format!("Database error: {e}")))?;
@@ -116,7 +97,6 @@ pub async fn create_folder(
Ok(Json(MessageResponse { status: "created" }).into_response())
}
/// `PATCH /api/folders/:name` -- rename an existing folder.
pub async fn rename_folder(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -139,7 +119,6 @@ pub async fn rename_folder(
.await
.map_err(|e| AppError::InternalError(format!("IMAP rename_folder failed: {e}")))?;
// Update the local cache.
let conn = db::pool::open_user_db(&config.data_dir, &session.user_hash)
.map_err(|e| AppError::InternalError(format!("Database error: {e}")))?;
@@ -151,7 +130,6 @@ pub async fn rename_folder(
Ok(Json(MessageResponse { status: "renamed" }).into_response())
}
/// `DELETE /api/folders/:name` -- delete a folder.
pub async fn delete_folder(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -171,7 +149,6 @@ pub async fn delete_folder(
.await
.map_err(|e| AppError::InternalError(format!("IMAP delete_folder failed: {e}")))?;
// Remove from local cache.
let conn = db::pool::open_user_db(&config.data_dir, &session.user_hash)
.map_err(|e| AppError::InternalError(format!("Database error: {e}")))?;
@@ -183,7 +160,6 @@ pub async fn delete_folder(
Ok(Json(MessageResponse { status: "deleted" }).into_response())
}
/// `PATCH /api/folders/:name/subscribe` -- toggle folder subscription.
pub async fn subscribe_folder(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -208,7 +184,6 @@ pub async fn subscribe_folder(
.into_response())
}
/// `POST /api/folders/:name/mark-all-read` -- add \Seen to every message.
pub async fn mark_all_read(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -237,7 +212,6 @@ pub async fn mark_all_read(
Ok(Json(MessageResponse { status: "read" }).into_response())
}
/// `POST /api/folders/:name/empty` -- permanently remove every message.
pub async fn empty_folder(
Extension(session): Extension<SessionState>,
Extension(config): Extension<Arc<AppConfig>>,
@@ -281,10 +255,6 @@ pub async fn empty_folder(
Ok(Json(MessageResponse { status: "emptied" }).into_response())
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;