From 645d8291934fb2845117ef7061e9411442ded4b9 Mon Sep 17 00:00:00 2001 From: Antfroze Date: Wed, 29 Apr 2026 18:44:08 -0500 Subject: [PATCH] docs: add README and register it in Cargo.toml --- Cargo.toml | 1 + README.md | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 README.md diff --git a/Cargo.toml b/Cargo.toml index 88ad9b9..8383d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Antfroze"] description = "Async Rust client for the Plunk transactional email API" license = "MIT" repository = "https://git.coldspire.com/Antfroze/plunk-rs" +readme = "README.md" keywords = ["plunk", "email", "transactional", "api"] categories = ["api-bindings", "email"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..ede7568 --- /dev/null +++ b/README.md @@ -0,0 +1,121 @@ +
+ +# plunk-rs + +**An async Rust client for [Plunk](https://www.useplunk.com/) transactional email.** + +*Send HTML, templates, and template variables (the `data` object) with validation, typed errors, and a small dependency footprint (reqwest + rustls).* + +[![License: MIT](https://img.shields.io/badge/License-MIT-5c6bc0.svg)](./LICENSE) +[![crates.io](https://img.shields.io/crates/v/plunk-rs.svg)](https://crates.io/crates/plunk-rs) +[![docs.rs](https://img.shields.io/docsrs/plunk-rs)](https://docs.rs/plunk-rs) + +[Repository](https://git.coldspire.com/Antfroze/plunk-rs) · [Plunk API](https://docs.useplunk.com) + +
+ +--- + +## Why this crate + +| | | +| :--- | :--- | +| **Focused** | Covers `POST /v1/send`—HTML and template sends, with optional `from`, `reply`, headers, and `data` for template variables. | +| **Validates early** | `Email` and `EmailAddress` are built with checks so bad requests fail before the wire. | +| **Clean boundary** | Wire DTOs stay internal; your code uses `Email`, `SendResponse`, and `Error`. | +| **TLS** | [reqwest](https://crates.io/crates/reqwest) with **rustls**—no OpenSSL at build time. | + +## Installation + +Add to `Cargo.toml`: + +```toml +[dependencies] +plunk-rs = "0.1" +tokio = { version = "1", features = ["rt-multi-thread", "macros"] } +``` + +Or: + +```text +cargo add plunk-rs +cargo add tokio --features rt-multi-thread,macros +``` + +## Quick start + +```rust +use plunk_rs::{Client, Email, EmailAddress}; + +#[tokio::main] +async fn main() -> Result<(), plunk_rs::Error> { + let client = Client::new("sk_your_plunk_api_key")?; + + let email = Email::html("user@example.com", "Welcome", "

Hello

")? + .from(EmailAddress::named("My app", "hello@yourdomain.com")?)? + .reply_to("support@yourdomain.com")?; + + let response = client.send(&email).await?; + + for delivery in response.deliveries() { + println!("{} → {}", delivery.contact().email(), delivery.id()); + } + Ok(()) +} +``` + +**Template send** (with data for the template): + +```rust +use plunk_rs::{Client, Email}; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), plunk_rs::Error> { + let client = Client::new("sk_your_plunk_api_key")?; + + let email = Email::template("user@example.com", "tpl_xxxxxxxx")? + .with_data(json!({ "first_name": "Ada" }))?; + + client.send(&email).await?; + Ok(()) +} +``` + +## Self-hosted or custom base URL + +```rust +let client = Client::builder("sk_xxx") + .base_url("https://plunk.example.com/api")? + .build()?; +``` + +`base_url` is normalized: if the path does not end with `/`, one is added so `v1/send` joins correctly. + +## API surface + +- **`Client` / `ClientBuilder`** — Bearer API key, optional `reqwest::Client` injection. +- **`Email`**, **`EmailAddress`**, **`Recipients`** — Construction helpers for HTML vs template, headers, and JSON `data` (must serialize to a JSON object for templates). +- **`SendResponse`**, **`Delivery`**, **`Contact`** — Parsed success payload from the send response. +- **`Error`**, **`ApiError`**, **`Result`** — Transport, validation, and Plunk error bodies (with status and raw body preserved). + +## Requirements + +Rust **2024** edition (use a current stable toolchain that supports it). Async code assumes a runtime such as **Tokio**. + +## Docs + +- [**docs.rs** — plunk-rs](https://docs.rs/plunk-rs) +- [Plunk documentation](https://docs.useplunk.com) + +## License + +[MIT](LICENSE) + +--- + +
+ +Made for sending mail through [Plunk](https://www.useplunk.com/) without the ceremony. + +