# pool-mod v0.2.0 — Foundation
**The public API arrives.** v0.2.0 turns the scaffold into a working pool: a
[`Manager`] trait for the resource lifecycle, a thread-safe [`Pool`] with blocking
acquisition and timeouts, an RAII [`Pooled`] guard, configurable sizing and
expiry, and a generic [`Error`] type. It ships with unit tests for every lifecycle
path, an eight-thread end-to-end integration test, and a rustdoc example on every
public item — green across Linux, macOS, and Windows on both stable and the MSRV.
Zero dependencies.
## What is pool-mod?
A generic object and connection pool for Rust. Implement one trait describing how
to create, validate, and recycle a resource, and the pool handles sizing, blocking
acquisition with timeouts, validation-on-borrow, and idle/lifetime expiry. It is
runtime-agnostic and pulls in no third-party crates.
## What's new in 0.2.0
### `Manager` — the resource lifecycle contract
The single trait you implement. `create` builds a resource, `recycle` resets a
returned one, and the optional `validate` hook is the validation-on-borrow / health
check that runs on checkout. The pool never holds its internal lock while calling
these, so a slow constructor or validator does not stall other threads.
```rust
use pool_mod::Manager;
use std::convert::Infallible;
struct Buffers { capacity: usize }
impl Manager for Buffers {
type Resource = Vec<u8>;
type Error = Infallible;
fn create(&self) -> Result<Vec<u8>, Infallible> {
Ok(Vec::with_capacity(self.capacity))
}
fn recycle(&self, buf: &mut Vec<u8>) -> Result<(), Infallible> {
buf.clear();
Ok(())
}
}
```
### `Pool` — the thread-safe pool
`Pool<M>` is `Send + Sync` and cheap to clone; each clone is another handle onto
the same shared pool. `get` borrows a resource, waiting up to the configured
`create_timeout`; `get_timeout` overrides the wait per call, and `Duration::ZERO`
turns it into a non-blocking try. `status`, `close`, and `is_closed` round out the
surface.
```rust
use pool_mod::{Manager, Pool};
# use std::convert::Infallible;
# struct Buffers { capacity: usize }
# impl Manager for Buffers {
# type Resource = Vec<u8>; type Error = Infallible;
# fn create(&self) -> Result<Vec<u8>, Infallible> { Ok(Vec::with_capacity(self.capacity)) }
# fn recycle(&self, b: &mut Vec<u8>) -> Result<(), Infallible> { b.clear(); Ok(()) }
# }
let pool = Pool::builder(Buffers { capacity: 4096 })
.max_size(16)
.min_idle(4)
.build()
.expect("configuration is valid");
let mut buf = pool.get().expect("a buffer is available");
buf.extend_from_slice(b"payload");
assert_eq!(pool.status().in_use, 1);
```
The acquisition loop reserves a slot, releases the lock, and only then runs the
manager's `create` / `validate` / `recycle`. The mutex guards just a small queue
and two counters; resource construction and user code always run unlocked.
### `Pooled` — RAII return
The guard returned by `get` deref-coerces to the resource and returns it to the
pool when dropped — recycled on the way back in. There is no `release` to forget,
and forgetting a guard cannot leak a resource. If `recycle` fails or the pool is
closed, the resource is dropped and its slot freed for a replacement. The guard is
`Send`, so it can be held across `.await` points.
The guard owns its resource through `ManuallyDrop` and moves it out exactly once,
in `Drop`. That is the crate's only `unsafe` block; it carries a `// SAFETY:`
proof and is covered by the check-in/return tests.
### `Builder` and `PoolConfig` — configuration
`PoolConfig` exposes `max_size`, `min_idle`, `create_timeout`, `idle_timeout`, and
`max_lifetime` as public fields with documented defaults (max 10, 30s create
timeout, no expiry). `Builder` is the fluent path; `build` validates the config —
rejecting a zero `max_size` or a `min_idle` above `max_size` with
`Error::InvalidConfig` — and pre-creates the `min_idle` resources.
### `Error` — generic over the manager's error
`Error<E>` carries the manager's own error unchanged in `Backend(E)`, alongside
`Timeout`, `Closed`, and `InvalidConfig`. It is `#[non_exhaustive]`, implements
`Display`, and implements `std::error::Error` (with `source()`) whenever `E` does.
### Lifecycle enforcement
Borrowing applies the full policy before handing a resource back: `max_lifetime`
and `idle_timeout` are checked against the resource's timestamps, then `validate`
runs. A resource that is too old, too stale, or invalid is dropped and the pool
supplies a replacement — the caller only ever receives a live resource.
### Documentation
`docs/API.md` now documents every public item with parameters, return values,
error semantics, and at least one runnable example, plus a Patterns section
(database connections, validation-on-borrow, cross-thread sharing, async usage).
The README is filled out with features, configuration, and a how-it-works section.
## Breaking changes
**None of consequence.** v0.1.0 had no public API beyond `VERSION`, which is
unchanged. Everything in this release is additive.
## Verification
Run on Windows x86_64 (Rust stable 1.95.0 and 1.75.0) and on Linux via WSL2
Ubuntu (Rust stable 1.95.0); these mirror the CI matrix.
```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo clippy --no-default-features --all-targets -- -D warnings
cargo test --all-features
cargo build --no-default-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo +1.75 build --all-features
cargo +1.75 test --all-features
```
All green. Counts at this tag: 18 unit tests, 3 integration tests, 1 smoke test,
and 16 doctests.
## What's next
- **0.5.0 — Implementation.** Property tests for the pool's invariants, broader
integration tests, Criterion benchmarks with tracked baselines, a background
idle reaper, and an opt-in native async acquisition API.
## Installation
```toml
[dependencies]
pool-mod = "0.2"
```
MSRV: Rust 1.75. Edition 2021.
## Documentation
- [README](https://github.com/jamesgober/pool-mod/blob/main/README.md)
- [API Reference](https://github.com/jamesgober/pool-mod/blob/main/docs/API.md)
- [CHANGELOG](https://github.com/jamesgober/pool-mod/blob/main/CHANGELOG.md)
---
**Full diff:** [`v0.1.0...v0.2.0`](https://github.com/jamesgober/pool-mod/compare/v0.1.0...v0.2.0).
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/pool-mod/blob/main/CHANGELOG.md#020---2026-05-27).
[`Manager`]: https://docs.rs/pool-mod/0.2.0/pool_mod/trait.Manager.html
[`Pool`]: https://docs.rs/pool-mod/0.2.0/pool_mod/struct.Pool.html
[`Pooled`]: https://docs.rs/pool-mod/0.2.0/pool_mod/struct.Pooled.html
[`Error`]: https://docs.rs/pool-mod/0.2.0/pool_mod/enum.Error.html