# Literator: Iterator formatting for literate programmers
This crate provides the `Literator` trait, which provides utilities for
efficiently displaying the items of an iterator without temporary allocations.
Additionally, a few general formatting utilities are provided for convenience,
including a polyfill for the unstable `std::fmt::from_fn()`, simple
Unicode-compatible case conversion display adapters, and repetition.
## Example use cases
Efficient, allocation-free string concatenation:
```rust
# use literator::Literator;
let favorite_things = ["raindrops", "roses", "whiskers", "kittens"];
// This does not allocate:
let joined = favorite_things.iter().capitalize_first().join(", ");
let message = joined.to_string();
assert_eq!(message, "Raindrops, roses, whiskers, kittens");
```
Some things require special display logic that cannot be represented as slices
without allocation, like paths:
```rust
# use literator::Literator;
# use std::path::Path;
let paths = [Path::new("foo"), Path::new("bar")];
```
Friendlier error messages with ad-hoc formatting:
```rust
# use literator::Literator;
#[derive(Debug, thiserror::Error)]
enum Crisis<'a> {
#[error(
"I need {}",
.0.iter().oxford_join_and()
)]
Craving(&'a [&'a str])
}
assert_eq!(
Crisis::Craving(&["pizza", "macaroni and cheese", "crackers"]).to_string(),
"I need pizza, macaroni and cheese, and crackers"
);
```
## Features
- Allocation-free. Custom `Debug`/`Display` implementations for various adapters
render directly to the output stream.
- General `join()`. The standard library only has
[`std::slice::join()`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.join),
which heap allocates and only works for slices, not iterators.
[`Itertools::join()`](https://docs.rs/itertools/latest/itertools/fn.join.html)
only works for `Display`, not `Debug`, and only supports using a `&str` as the delimiter.
- General `oxford_join()` for listing items with appropriate punctuation. The
[`oxford_join`
crate](https://docs.rs/oxford_join/latest/oxford_join/index.html), while
great, only works on slices and collections, heap allocates the result, and
only supports string conjunctions. `Literator::oxford_join_custom()` supports
using any displayable delimiter, including non-English conjunctions.
- Prefix/suffix/surround each item: Adapters for adding prefixes/suffixes to the
items of an iterator while displaying them.
- Adapters forward all formatting options to the item being displayed. For
example, `println!("{:.02}", [1.0, 2.0].iter().join(", "))` prints `"1.00,
2.00"`.
- Zero dependencies.
- `#![no_std]`
- `#![forbid(unsafe_code)]`