Skip to main content

Literator

Trait Literator 

Source
pub trait Literator {
    type Item;
    type Iter: Iterator<Item = Self::Item>;

Show 25 methods // Required method fn into_option_iter(self) -> Option<Self::Iter>; // Provided methods fn join<D>(self, delim: D) -> Join<Self::Iter, D> where Self: Sized, D: Display { ... } fn concat(self) -> Literate<Self::Iter> where Self: Sized { ... } fn conjunctive_join_custom<Delim, LastDelim>( self, delim: Delim, last_delim: LastDelim, ) -> ConjunctiveJoin<Self::Iter, Delim, LastDelim> where Self: Sized, Delim: Display, LastDelim: Display { ... } fn join_and(self) -> ConjunctiveJoin<Self::Iter> where Self: Sized { ... } fn join_or(self) -> ConjunctiveJoin<Self::Iter> where Self: Sized { ... } fn join_comma_and(self) -> ConjunctiveJoin<Self::Iter> where Self: Sized { ... } fn join_comma_or(self) -> ConjunctiveJoin<Self::Iter> where Self: Sized { ... } fn oxford_join_custom<Delim, ExactlyTwo, Final>( self, first_n: Delim, exactly_two_conjunction: ExactlyTwo, final_delim_conjunction: Final, ) -> OxfordJoin<Self::Iter, Delim, ExactlyTwo, Final> where Self: Sized, Delim: Display, ExactlyTwo: Display, Final: Display { ... } fn oxford_join_and(self) -> OxfordJoin<Self::Iter> where Self: Sized { ... } fn oxford_join_or(self) -> OxfordJoin<Self::Iter> where Self: Sized { ... } fn oxford_join_semicolon_and(self) -> OxfordJoin<Self::Iter> where Self: Sized { ... } fn oxford_join_semicolon_or(self) -> OxfordJoin<Self::Iter> where Self: Sized { ... } fn format_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = FormatWith<Self::Item, F>>> where Self: Sized, F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone { ... } fn capitalize_first(self) -> Literate<impl Iterator<Item: Display>> where Self: Sized, Self::Item: Display { ... } fn prefix_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = PrefixWith<Self::Item, F>>> where F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone, Self: Sized { ... } fn suffix_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = SuffixWith<Self::Item, F>>> where F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone, Self: Sized { ... } fn prefix_each<P>( self, prefix: P, ) -> Literate<impl Iterator<Item = Prefix<Self::Item, P>>> where P: Display + Clone, Self: Sized { ... } fn suffix_each<S>( self, suffix: S, ) -> Literate<impl Iterator<Item = Suffix<Self::Item, S>>> where S: Display + Clone, Self: Sized { ... } fn surround_each<P, S>( self, prefix: P, suffix: S, ) -> Literate<impl Iterator<Item = Surround<Self::Item, P, S>>> where P: Display + Clone, S: Display + Clone, Self: Sized { ... } fn indent_each( self, level: usize, ) -> Literate<impl Iterator<Item = Surround<Self::Item, Repeat<&'static str>, char>>> where Self: Sized { ... } fn indent_each_custom<P, S>( self, level: usize, indentation: P, newline: S, ) -> Literate<impl Iterator<Item = Surround<Self::Item, Repeat<P>, S>>> where P: Display + Clone, S: Display + Clone, Self: Sized { ... } fn indented_block<Open, Close>( self, open: Open, close: Close, inner_level: usize, ) -> IndentedBlock<Self::Iter, Open, Close, &'static str, char> where Self: Sized, Open: Display, Close: Display { ... } fn indented_block_custom<Open, Close, Indentation, Newline>( self, open: Open, close: Close, inner_level: usize, indentation: Indentation, newline: Newline, ) -> IndentedBlock<Self::Iter, Open, Close, Indentation, Newline> where Self: Sized, Open: Display, Close: Display, Indentation: Display, Newline: Display { ... } fn inline_block<P, D, S>( self, open: P, delim: D, close: S, ) -> InlineBlock<Self::Iter, P, D, S> where Self: Sized, P: Display, D: Display, S: Display { ... }
}
Expand description

Iterator extension trait for efficient Display/Debug.

See crate-level documentation for more information.

Required Associated Types§

Source

type Item

The item that this literator is displaying.

Source

type Iter: Iterator<Item = Self::Item>

The iterator type that this literator wraps.

Required Methods§

Source

fn into_option_iter(self) -> Option<Self::Iter>

Convert this literator into an Option of its iterator.

Provided Methods§

Source

fn join<D>(self, delim: D) -> Join<Self::Iter, D>
where Self: Sized, D: Display,

Wrap the iterator in an object implementing Display/Debug that prints each item separated by a delimiter.

This does not allocate, but does consumes the iterator when Display::fmt(), Debug::fmt(), or another formatting trait is used. Subsequent uses of the same Join object will print the empty string.

§Example
let items = ["Foo", "Bar"];
let joined = items.iter().join(", ").to_string();
assert_eq!(joined, "Foo, Bar");

// Formatting options are forwarded.
let joined = format!("{:04x}", [10, 20, 30].iter().join(", "));
assert_eq!(joined, "000a, 0014, 001e");

let floats = format!("{:0.02}", [1.0, 2.0].iter().join(" "));
assert_eq!(floats, "1.00 2.00");
Source

fn concat(self) -> Literate<Self::Iter>
where Self: Sized,

Concatenate all items into a single string, using each item’s Display or Debug implementation.

This is equivalent to .join(Empty).

§Example
let chars = ['a', 'b', 'c'];
assert_eq!(
    chars.iter().map(Uppercase).concat().to_string(),
    "ABC",
);
Source

fn conjunctive_join_custom<Delim, LastDelim>( self, delim: Delim, last_delim: LastDelim, ) -> ConjunctiveJoin<Self::Iter, Delim, LastDelim>
where Self: Sized, Delim: Display, LastDelim: Display,

Join the items using delim between the first N-1 elements, and last_delim between the next-to-last and last items.

This is the same as oxford_join_custom(), but without the special case for exactly two elements.

§Example
let recipients = ["God", "Alice and Bob", "Charlie"];
assert_eq!(
    recipients.iter().conjunctive_join_custom(", ", ", and ").to_string(),
    "God, Alice and Bob, and Charlie"
);
Source

fn join_and(self) -> ConjunctiveJoin<Self::Iter>
where Self: Sized,

Join the items separated by ", " between each item, except " and " (no comma) between the next-to-last and last items.

§Example
let fruits = ["apples", "oranges", "bananas"];
assert_eq!(
    fruits.iter().join_and().to_string(),
    "apples, oranges and bananas",
);
Source

fn join_or(self) -> ConjunctiveJoin<Self::Iter>
where Self: Sized,

Join the items separated by ", " between each item, except " or " (no comma) between the next-to-last and last items.

Source

fn join_comma_and(self) -> ConjunctiveJoin<Self::Iter>
where Self: Sized,

Join the items separated by ", " between each item, except ", and " (with comma) between the next-to-last and last items.

§Example
let fruits = ["apples", "oranges", "bananas"];
assert_eq!(
    fruits.iter().join_comma_and().to_string(),
    "apples, oranges, and bananas",
);
Source

fn join_comma_or(self) -> ConjunctiveJoin<Self::Iter>
where Self: Sized,

Join the items separated by ", " between each item, except ", or " (with comma) between the next-to-last and last items.

Source

fn oxford_join_custom<Delim, ExactlyTwo, Final>( self, first_n: Delim, exactly_two_conjunction: ExactlyTwo, final_delim_conjunction: Final, ) -> OxfordJoin<Self::Iter, Delim, ExactlyTwo, Final>
where Self: Sized, Delim: Display, ExactlyTwo: Display, Final: Display,

Join items using serial comma (“Oxford comma”, “Harvard comma”).

Turns this iterator into an object that implements Display and/or Debug. All formatting options are forwarded to each item.

  • Items are formatted using Debug or Display based on whether the returned object is formatted using Debug or Display.
  • When the iterator is empty (N=0), nothing is printed.
  • When the iterator has exactly one element (N=1), no separators are emitted.
  • When the iterator has exactly two elements (N=2), the {exactly_two} conjunction is the only separator (typically " and ", no comma).
  • When the iterator has three or more elements (N>=3), {first_n} is written between all elements, except that {final_delim_conjunction} is emitted between the next-to-last and last element, and exactly_two_conjunction is unused.

Note: This function does not add any spaces around the delimiters/conjunctions, which is why it takes three arguments.

To get a standard Oxford list, you would call this as iter.oxford_join_custom(", ", " and ", ", and "), which is what oxford_join_and() does.

Source

fn oxford_join_and(self) -> OxfordJoin<Self::Iter>
where Self: Sized,

Oxford join with commas and English “and”.

See also Literator::oxford_join_custom().

§Example
let items = ["Parsley", "Sage", "Rosemary", "Thyme"];
let line = items.iter().oxford_join_and().to_string();
assert_eq!(line, "Parsley, Sage, Rosemary, and Thyme");

let just_two = ["Pride", "Prejudice"];
let title = just_two.iter().oxford_join_and().to_string();
assert_eq!(title, "Pride and Prejudice");
Source

fn oxford_join_or(self) -> OxfordJoin<Self::Iter>
where Self: Sized,

Oxford join with commas and English “or”.

See also Literator::oxford_join_custom().

Source

fn oxford_join_semicolon_and(self) -> OxfordJoin<Self::Iter>
where Self: Sized,

Oxford join with semicolons and English “and”.

See also Literator::oxford_join_custom().

Source

fn oxford_join_semicolon_or(self) -> OxfordJoin<Self::Iter>
where Self: Sized,

Oxford join with semicolons and English “or”.

See also Literator::oxford_join_custom().

Source

fn format_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = FormatWith<Self::Item, F>>>
where Self: Sized, F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone,

Produce an iterator where each item’s Display/Debug implementation is overridden by the function with.

This is essentially short-hand for .map(|item| fmt::from_fn(move |f| ...)). See fmt::from_fn().

§Example
let hex_numbers = [10, 20, 30]
    .iter()
    .format_each_with(|n, f| write!(f, "{n:#04x}"))
    .oxford_join_and()
    .to_string();
assert_eq!(hex_numbers, "0x0a, 0x14, and 0x1e");

// Capitalize the first item
let items = ["apples", "oranges", "pears"];
assert_eq!(
    items
        .iter()
        .enumerate()
        .format_each_with(|(index, thing), f| if *index == 0 {
            write!(f, "{}", Capitalize(thing))
        } else {
            write!(f, "{thing}")
        })
        .oxford_join_and()
        .to_string(),
    "Apples, oranges, and pears",
);

// The returned object itself also implements `Display`:
assert_eq!(
    items
        .iter()
        .format_each_with(|thing, f| write!(f, "{}", Capitalize(thing)))
        .to_string(),
    "ApplesOrangesPears",
);
Source

fn capitalize_first(self) -> Literate<impl Iterator<Item: Display>>
where Self: Sized, Self::Item: Display,

Capitalize the first item in the list.

Due to current limitations in the standard library, this only works for Display, not other formatting traits.

To capitalize all items, use .map(Capitalize) instead.

§Example
let items = ["apples", "oranges", "pears"];
assert_eq!(
    items
        .iter()
        .capitalize_first()
        .oxford_join_and()
        .to_string(),
    "Apples, oranges, and pears",
);
Source

fn prefix_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = PrefixWith<Self::Item, F>>>
where F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone, Self: Sized,

Produce an iterator where each item’s Display/Debug implementation writes a custom prefix before the item.

§Example
let numbers = 1..=5;
let even_list = numbers
    .into_iter()
    .prefix_each_with(|n, f| if *n % 2 == 0 { write!(f, "* ") } else { Ok (()) })
    .join('\n')
    .to_string();
assert_eq!(even_list,
"1
* 2
3
* 4
5");
Source

fn suffix_each_with<F>( self, with: F, ) -> Literate<impl Iterator<Item = SuffixWith<Self::Item, F>>>
where F: Fn(&Self::Item, &mut Formatter<'_>) -> Result + Clone, Self: Sized,

Produce an iterator where each item’s Display/Debug implementation writes a custom suffix after the item.

§Example
let numbers = 1..=10;
let even_list = numbers
    .into_iter()
    .suffix_each_with(|n, f| if *n % 2 == 0 { write!(f, " *") } else { Ok (()) })
    .join('\n')
    .to_string();
assert_eq!(even_list, "1\n2 *\n3\n4 *\n5\n6 *\n7\n8 *\n9\n10 *");
Source

fn prefix_each<P>( self, prefix: P, ) -> Literate<impl Iterator<Item = Prefix<Self::Item, P>>>
where P: Display + Clone, Self: Sized,

Produce an iterator where each item’s Display/Debug implementation writes prefix before the item.

§Example
let items = ["Milk", "Eggs", "Tampons"];
let shopping_list = items.iter().prefix_each("- ").join('\n').to_string();
assert_eq!(shopping_list, "- Milk\n- Eggs\n- Tampons");
Source

fn suffix_each<S>( self, suffix: S, ) -> Literate<impl Iterator<Item = Suffix<Self::Item, S>>>
where S: Display + Clone, Self: Sized,

Produce an iterator where each item’s Display/Debug implementation writes suffix after the item.

§Example
let words = ["Fresh", "Innovative", "Placemaking", "Disposable duvets", "Growth hacking"];
let message = words.iter().suffix_each('.').join(' ').to_string();
assert_eq!(message, "Fresh. Innovative. Placemaking. Disposable duvets. Growth hacking.");
Source

fn surround_each<P, S>( self, prefix: P, suffix: S, ) -> Literate<impl Iterator<Item = Surround<Self::Item, P, S>>>
where P: Display + Clone, S: Display + Clone, Self: Sized,

Produce an iterator where each item’s Display/Debug implementation writes prefix before and suffix after the item.

This is shorthand for .suffix_each(suffix).prefix_each(prefix).

§Example
let items = ["Foo", "Bar"];
let list = items.iter().surround_each('(', ')').to_string();
assert_eq!(list, "(Foo)(Bar)");
Source

fn indent_each( self, level: usize, ) -> Literate<impl Iterator<Item = Surround<Self::Item, Repeat<&'static str>, char>>>
where Self: Sized,

Print each item prefixed by indentation, where each level of indentation is 4 spaces, and suffix each item with a newline.

§Example
let numbers = format!("\n{}", [1, 2, 3].iter().prefix_each("- ").indent_each(1));
assert_eq!(numbers, "
    - 1
    - 2
    - 3
");
Source

fn indent_each_custom<P, S>( self, level: usize, indentation: P, newline: S, ) -> Literate<impl Iterator<Item = Surround<Self::Item, Repeat<P>, S>>>
where P: Display + Clone, S: Display + Clone, Self: Sized,

Print each item with custom indentation. The indentation string is repeated level times before each item, and newline is appended after each item.

Source

fn indented_block<Open, Close>( self, open: Open, close: Close, inner_level: usize, ) -> IndentedBlock<Self::Iter, Open, Close, &'static str, char>
where Self: Sized, Open: Display, Close: Display,

Print items in a block surrounded by open and close, indented by inner_level.

When there are zero items, the open and close tokens are printed without any spacing or newline.

When there are one or more items: A newline is added after the open token, and each item is printed with default indentation (four spaces per level) on a separate line, and the closing delimiter is placed on a separate line with indentation corresponding to inner_level-1.

§Example
let empty: &[i32] = &[];
assert_eq!(empty.iter().indented_block('{', '}', 1).to_string(), "{}");

let two = &[1, 2];
assert_eq!(format!("\n{}", two.iter().indented_block('{', '}', 1)), "
{
    1
    2
}");

let map = BTreeMap::from_iter([("hello", 123), ("world", 456)]);
assert_eq!(
    format!("\n{}", map
        .iter()
        .format_each_with(|(key, value), f| write!(f, "{key}: {value},"))
        .indented_block('{', '}', 1)),
    "
{
    hello: 123,
    world: 456,
}");
Source

fn indented_block_custom<Open, Close, Indentation, Newline>( self, open: Open, close: Close, inner_level: usize, indentation: Indentation, newline: Newline, ) -> IndentedBlock<Self::Iter, Open, Close, Indentation, Newline>
where Self: Sized, Open: Display, Close: Display, Indentation: Display, Newline: Display,

Same as indented_block(), but with custom indentation and newline tokens.

indentation is printed for each indentation level. newline is printed after each item, as well as after open.

Source

fn inline_block<P, D, S>( self, open: P, delim: D, close: S, ) -> InlineBlock<Self::Iter, P, D, S>
where Self: Sized, P: Display, D: Display, S: Display,

Print items in a block surrounded by open and close, where items are delimited by delim.

When there are zero items, the open and close tokens are printed without any spacing, but when there are one or more items, a space is added after the opening token and before the closing token. This is what distinguishes inline_block() from simply using join(delim) surrounded by the open/close tokens.

§Example
let empty: &[i32] = &[];
assert_eq!(empty.iter().inline_block('[', ',', ']').to_string(), "[]");

let one = &[1];
assert_eq!(one.iter().inline_block('[', ',', ']').to_string(), "[ 1 ]");

let two = &[1, 2];
assert_eq!(two.iter().inline_block('[', ", ", ']').to_string(), "[ 1, 2 ]");

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<I: Iterator> Literator for I

Source§

type Item = <I as Iterator>::Item

Source§

type Iter = I

Source§

impl<I> Literator for Literate<I>
where I: Iterator + Sized,

Source§

type Item = <I as Iterator>::Item

Source§

type Iter = I