# EuroMail Rust SDK

Official Rust SDK for the [EuroMail](https://euromail.dev) transactional email service.

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
euromail = "0.1"
```

## Quick Start

```rust
use euromail::{EuroMail, SendEmailParams};

#[tokio::main]
async fn main() -> Result<(), euromail::EuroMailError> {
    let client = EuroMail::new("your-api-key");

    let params = SendEmailParams {
        from: "you@yourdomain.com".to_string(),
        to: "recipient@example.com".to_string(),
        subject: Some("Hello from EuroMail".to_string()),
        html_body: Some("<h1>Welcome!</h1><p>Thanks for signing up.</p>".to_string()),
        text_body: None,
        cc: None,
        bcc: None,
        reply_to: None,
        template_alias: None,
        template_data: None,
        headers: None,
        tags: None,
        metadata: None,
        attachments: None,
        idempotency_key: None,
    };

    let response = client.send_email(&params).await?;
    println!("Sent! ID: {}", response.id);

    Ok(())
}
```

## Usage

### Account

```rust
let account = client.get_account().await?;
println!("Plan: {}, Quota: {}", account.plan, account.monthly_quota);
```

### Sending Emails

```rust
// Single email
let response = client.send_email(&params).await?;

// Batch send
let batch = SendBatchParams {
    emails: vec![params1, params2],
};
let batch_response = client.send_batch(&batch).await?;
```

### Templates

```rust
use euromail::{CreateTemplateParams, UpdateTemplateParams};

let template = client.create_template(&CreateTemplateParams {
    alias: "welcome".to_string(),
    name: "Welcome Email".to_string(),
    subject: "Welcome, {{name}}!".to_string(),
    html_body: Some("<h1>Welcome, {{name}}!</h1>".to_string()),
    text_body: None,
}).await?;

let templates = client.list_templates(None).await?;
```

### Domains

```rust
let domain = client.add_domain("mail.example.com").await?;
let verification = client.verify_domain(&domain.id).await?;
if verification.fully_verified {
    println!("Domain verified!");
}
```

### Webhooks

```rust
use euromail::CreateWebhookParams;

let webhook = client.create_webhook(&CreateWebhookParams {
    url: "https://example.com/webhook".to_string(),
    events: vec!["delivered".to_string(), "bounced".to_string()],
}).await?;
```

### Suppressions

```rust
client.add_suppression("spam@example.com", None).await?;
client.delete_suppression("spam@example.com").await?;
let suppressions = client.list_suppressions(None).await?;
```

### Contact Lists

```rust
use euromail::{CreateContactListParams, AddContactParams, BulkAddContactsParams};

let list = client.create_contact_list(&CreateContactListParams {
    name: "Newsletter".to_string(),
    description: Some("Monthly newsletter subscribers".to_string()),
    double_opt_in: Some(true),
}).await?;

let contact = client.add_contact(&list.id, &AddContactParams {
    email: "user@example.com".to_string(),
    metadata: None,
}).await?;

let bulk = client.bulk_add_contacts(&list.id, &BulkAddContactsParams {
    contacts: vec![
        AddContactParams { email: "a@example.com".to_string(), metadata: None },
        AddContactParams { email: "b@example.com".to_string(), metadata: None },
    ],
}).await?;
```

### Analytics

```rust
use euromail::AnalyticsQuery;

let overview = client.get_analytics_overview(Some(&AnalyticsQuery {
    period: Some("30d".to_string()),
    from: None,
    to: None,
})).await?;

let csv = client.export_analytics_csv(None).await?;
```

### Audit Logs

```rust
let logs = client.list_audit_logs(None).await?;
for log in &logs.data {
    println!("{}: {} on {}", log.created_at, log.action, log.resource_type);
}
```

## Error Handling

All methods return `Result<T, EuroMailError>`. Error variants:

- `Authentication` - Invalid or missing API key (401)
- `Validation` - Invalid request parameters (422)
- `RateLimit` - Too many requests, includes `retry_after` hint (429)
- `NotFound` - Resource does not exist (404)
- `Api` - Other API errors (4xx/5xx)
- `Http` - Network / transport errors

```rust
match client.get_account().await {
    Ok(account) => println!("Account: {}", account.name),
    Err(EuroMailError::RateLimit { retry_after, .. }) => {
        if let Some(secs) = retry_after {
            tokio::time::sleep(std::time::Duration::from_secs(secs)).await;
        }
    }
    Err(e) => eprintln!("Error: {e}"),
}
```

## License

MIT
