# AGENTS.md - br-email
## Project Overview
br-email is a Rust library for email operations supporting IMAP, POP3, and SMTP protocols.
It provides email receiving, sending, and parsing capabilities with TLS support.
## Build Commands
```bash
# Build the project
cargo build
# Build with all features (default)
cargo build --all-features
# Build with specific features
cargo build --features "imap pop3 smtp"
cargo build --features "imap"
cargo build --features "pop3"
cargo build --features "smtp"
# Release build
cargo build --release
# Check without building
cargo check
```
## Test Commands
```bash
# Run all tests
cargo test
# Run a single test by name
cargo test test_name
cargo test get_total
# Run tests in a specific module
cargo test imap_qq::
cargo test pop3_qq::
cargo test smtp::
# Run a specific test file
cargo test --test imap
cargo test --test pop3
cargo test --test smtp
# Run tests with output
cargo test -- --nocapture
# Run ignored tests
cargo test -- --ignored
```
## Lint & Format
```bash
# Format code
cargo fmt
# Check formatting without changes
cargo fmt --check
# Run clippy linter
cargo clippy
# Run clippy with all features
cargo clippy --all-features
```
## Project Structure
```
src/
lib.rs # Main library entry, Mail struct, Receive/Sender traits
analyze.rs # Email parsing (AnalyzeEmails struct)
pools.rs # Thread pool implementation
imap/
mod.rs # IMAP client implementation
server.rs # IMAP server connection handling
pop3/
mod.rs # POP3 client implementation
server.rs # POP3 server connection handling
smtp/
mod.rs # SMTP client using lettre
tests/
imap.rs # IMAP integration tests
pop3.rs # POP3 integration tests
smtp.rs # SMTP integration tests
```
## Code Style Guidelines
### Imports
Order imports as follows:
1. Standard library (`std::`)
2. External crates
3. Internal crate modules (`crate::`)
```rust
use std::io::{Error, Read, Write};
use std::net::TcpStream;
use native_tls::{TlsConnector, TlsStream};
use serde::{Deserialize, Serialize};
use crate::{EmailType, Receive, Sender};
```
### Error Handling
- Use `std::io::Error` as the primary error type
- Use `Error::other()` for custom error messages
- Return `Result<T, Error>` from fallible functions
- Error messages should be descriptive (Chinese comments are acceptable)
```rust
// Good
Err(Error::other(format!("邮件POP3服务器连接失败: {host} {e}")))
// Good
Err(Error::other("请填写收件人".to_string()))
```
### Naming Conventions
- Structs: PascalCase (`Mail`, `AnalyzeEmails`, `Server`)
- Functions/methods: snake_case (`get_total`, `get_id_list`)
- Constants: SCREAMING_SNAKE_CASE
- Enums: PascalCase with PascalCase variants (`Protocol::POP3`, `EmailType::Google`)
- Private fields: snake_case with doc comments
### Types
- Use `String` for owned strings, `&str` for borrowed
- Use `Vec<u8>` for binary data
- Use `HashMap<String, String>` for key-value pairs (e.g., email addresses)
- Use `Box<dyn Trait>` for trait objects
- Use feature flags for optional functionality
```rust
#[cfg(feature = "imap")]
use crate::imap::Imap;
```
### Struct Design
- Use `#[derive(Clone, Debug)]` for data structs
- Add `Deserialize, Serialize` for config structs
- Document fields with `///` comments (Chinese is acceptable)
```rust
#[derive(Clone, Debug)]
pub struct Mail {
/// 协议
protocol: Protocol,
/// 邮件地址
host: String,
/// 邮件端口
port: u16,
}
```
### Trait Implementation
The codebase uses two main traits:
- `Receive`: For receiving emails (`get_total`, `get_id_list`, `get_id_info`, `del_id`)
- `Sender`: For sending emails (`send`, `set_from`, `set_to`, `set_cc`, `set_subject`, `set_body`, `set_file`)
Implement both traits for protocol structs, use `todo!()` for unsupported operations.
### TLS/SSL Handling
- Port 993 = IMAP with TLS
- Port 995 = POP3 with TLS
- Port 25/587 = SMTP with STARTTLS
- Use `native_tls::TlsConnector` for TLS connections
### String Handling
- Use `format!()` for string formatting
- Use `.leak()` sparingly for static string conversion
- Use `unsafe { String::from_utf8_unchecked() }` only when data is known to be valid UTF-8
### Testing
- Use `#[cfg(test)]` module for tests
- Group tests by protocol (`mod imap_qq`, `mod pop3_qq`)
- Create helper functions for mail client setup
- Use `println!()` for test output with `-- --nocapture`
```rust
#[cfg(test)]
mod imap_qq {
use br_email::{Mail, Receive};
fn mail() -> Box<dyn Receive> {
Mail::new("imap", "host", 993, "name", "user", "pass").receive()
}
#[test]
fn get_total() {
let size = mail().get_total().unwrap();
println!("{size}");
}
}
```
## Feature Flags
```toml
[features]
smtp = ["lettre"]
pop3 = []
imap = []
default = ["imap", "pop3", "smtp"]
```
## Dependencies
Key dependencies:
- `native-tls`: TLS/SSL connections
- `lettre`: SMTP email sending (optional)
- `serde` + `toml`: Configuration serialization
- `chrono`: Date/time handling
- `regex`: Pattern matching for email parsing
- `br-crypto`: Encoding (base64, MD5, etc.)
## Common Patterns
### Creating a mail client
```rust
let mut mail = Mail::new("imap", "imap.gmail.com", 993, "name", "user@gmail.com", "password");
let receiver = mail.receive();
let total = receiver.get_total()?;
```
### Parsing emails
```rust
let data: Vec<u8> = /* raw email bytes */;
let parsed = Mail::analyze(data, false)?; // false = no debug output
println!("Subject: {}", parsed.subject);
```