This document describes the architecture and design of RSendMail, a high-performance bulk email sending tool.
RSendMail is a Rust-based application for testing and sending bulk emails via SMTP. It provides both CLI and GUI interfaces, sharing a common core library.
┌─────────────────────────────────────────────────────────┐
│ Applications │
├──────────────────────┬──────────────────────────────────┤
│ rsendmail-cli │ rsendmail-gui │
│ (Command Line) │ (Slint GUI) │
├──────────────────────┴──────────────────────────────────┤
│ rsendmail-core │
│ (Email Sending Engine) │
├─────────────────────────────────────────────────────────┤
│ rsendmail-i18n │
│ (Internationalization) │
└─────────────────────────────────────────────────────────┘
RSendMail/
├── Cargo.toml # Workspace configuration
├── crates/
│ ├── rsendmail-i18n/ # Internationalization support
│ │ ├── src/lib.rs # Language enum, tr() functions
│ │ └── locales/ # YAML translation files
│ │ ├── en-US.yml # English (fallback)
│ │ ├── zh-CN.yml # Simplified Chinese
│ │ ├── zh-TW.yml # Traditional Chinese
│ │ └── ja-JP.yml # Japanese
│ │
│ ├── rsendmail-core/ # Core library
│ │ └── src/
│ │ ├── lib.rs # Library exports
│ │ ├── config.rs # Configuration structure
│ │ ├── mailer.rs # Email sending engine (~1800 lines)
│ │ ├── stats.rs # Statistics collection
│ │ └── anonymizer.rs # Email anonymization
│ │
│ ├── rsendmail-cli/ # CLI application
│ │ └── src/
│ │ ├── main.rs # Entry point, loop control
│ │ ├── args.rs # CLI argument parsing (clap builder)
│ │ └── logging.rs # Log initialization
│ │
│ └── rsendmail-gui/ # GUI application
│ ├── src/
│ │ ├── main.rs # GUI entry point
│ │ └── i18n.rs # GUI-specific i18n
│ ├── ui/
│ │ └── app.slint # UI definition
│ └── fonts/ # Custom fonts
│
├── assets/
│ └── screenshots/ # GUI screenshots
│
└── docs/
└── ARCHITECTURE.md # This file
rsendmail-cli ──┬──► rsendmail-core ──► rsendmail-i18n
│
└──► rsendmail-i18n
rsendmail-gui ──┬──► rsendmail-core ──► rsendmail-i18n
│
└──► (GUI has its own i18n via HashMap)
Shared internationalization module using rust-i18n library.
Features:
- 4 supported languages: English, Simplified Chinese, Traditional Chinese, Japanese
- Language detection from environment variables and system locale
- Translation functions:
tr(key)andtr_with_args(key, args) - YAML-based translation files (~250 keys per language)
Language Detection Priority:
--langCLI argumentRSENDMAIL_LANGenvironment variableLANG/LC_ALLenvironment variables- macOS
AppleLocale(on macOS) - Default to English
The core email sending engine, shared by CLI and GUI.
Modules:
Configstruct with 30+ configuration options- Serde serialization support for save/load
- Default values for all optional fields
ProcessModeenum (Auto / Fixed)
The main email sending logic with three operating modes:
-
EML Mode (
--dir)- Reads EML files from a directory
- Supports batch sending in single SMTP session
- Multi-process parallel sending
-
Attachment Mode (
--attachment)- Sends a single file as email attachment
- Auto-detects MIME type
- Template support for subject/body
-
Attachment Directory Mode (
--attachment-dir)- Sends each file in directory as separate email
- Same template support as single attachment
Connection Handling:
- Plain text connection (port 25)
- STARTTLS (port 587)
- Implicit TLS (port 465)
- SMTP authentication (username/password)
- Connection timeout and retry logic
- Connection problem detection (421 errors, broken pipe)
Statsstruct for tracking:- Email count (total, success, failed)
- Parse/send durations
- Error classification with file lists
- QPS (queries per second) calculation
- Implements
Displaytrait for formatted output
- Replaces email addresses with random strings
- Maintains consistency (same email → same replacement)
- Uses HashMap for caching
Command-line interface application.
Features:
- 30+ command-line options
- Localized
--helpoutput - Graceful shutdown (Ctrl+C handling)
- Loop and repeat modes
- Optional log file output
- Failed email saving
Architecture:
- Uses clap builder pattern (not derive) for runtime i18n
- Early language detection before CLI parsing
- Tokio async runtime
Graphical user interface using Slint framework.
Features:
- Visual SMTP configuration
- Three sending modes with mode-specific UI
- Real-time progress and statistics
- Log viewing with export
- Configuration save/load (JSON)
- Language switcher
- Custom logger for dual output (terminal + GUI)
UI Components:
- Main window with tabbed sections
- SMTP server settings panel
- Send mode selector
- Advanced options panel
- Statistics display
- Log viewer
main.rs
│
├─► detect_language() ──► set_language()
│
├─► parse_args() ──► Config
│
├─► init_logging()
│
├─► Mailer::new(config)
│
└─► Loop:
│
├─► mailer.send_all_with_cancel(running)
│ │
│ ├─► EML mode: collect_email_files() → send_fixed_mode()
│ ├─► Attachment mode: send_attachment_with_cancel()
│ └─► Attachment-dir mode: send_attachment_dir_with_cancel()
│
├─► Accumulate Stats
│
└─► Wait for next iteration (if loop/repeat)
main.rs
│
├─► init_logger() (GuiLogger)
│
├─► AppWindow::new()
│
├─► setup_i18n()
│
├─► setup_callbacks()
│ │
│ ├─► on_start_send() ──► spawn async task
│ │ │
│ │ └─► Mailer::send_all_with_cancel()
│ │ │
│ │ └─► Send events via mpsc channel
│ │
│ ├─► on_stop_send() ──► set running = false
│ │
│ ├─► on_browse_*() ──► file dialogs
│ │
│ └─► on_save/load_config() ──► JSON serialize/deserialize
│
└─► app.run()
| Dependency | Purpose |
|---|---|
| tokio | Async runtime |
| mail-send | SMTP client |
| mail-parser | EML file parsing |
| mail-builder | Email construction |
| clap | CLI argument parsing |
| slint | GUI framework |
| rust-i18n | Internationalization |
| serde | Configuration serialization |
| walkdir | Directory traversal |
| infer | MIME type detection |
anyhow::Resultfor application-level errorsStats.increment_error()for per-email error tracking- Error classification by type (connection, auth, send, parse)
- Failed email file saving for later analysis
Arc<AtomicBool>for graceful shutdown signalingArc<Mutex<...>>for shared state in GUI logger- Tokio channels for GUI event communication
- Per-process stats in multi-process mode
The Config struct supports:
- Direct field access in code
- JSON serialization for GUI save/load
- CLI argument parsing
- Default values for all optional fields
- Additional email providers beyond SMTP
- Email template library
- Scheduling and queue management
- Web-based dashboard
- Plugin system for custom processors