/literator

Iterator formatting for literate programmers

Primary LanguageRustMIT LicenseMIT

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:

# 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:

# use literator::Literator;
# use std::path::Path;
let paths = [Path::new("foo"), Path::new("bar")];
let list = paths.iter().map(|p| p.display()).join(", ").to_string();
assert_eq!(list, "foo, bar");

Friendlier error messages with ad-hoc formatting:

# 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(), which heap allocates and only works for slices, not iterators. Itertools::join() 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, 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)]