kutil 0.0.6

Kutil utilities collection
Documentation
use super::super::iter::*;

/// Join with conjunction.
pub trait JoinConjunction<'this> {
    /// Join iterated strings as human-readable in English with a conjunction
    /// and an Oxford comma.
    ///
    /// Examples:
    ///
    /// * `one`
    /// * `one or two`
    /// * `one, two, or three`
    /// * `one, two, three, or four`
    fn join_conjunction(&'this self, conjunction: &str) -> String;
}

impl<'this, IterableT, ItemT> JoinConjunction<'this> for IterableT
where
    &'this IterableT: 'this + IntoIterator<Item = ItemT>,
    ItemT: 'this + AsRef<str>,
{
    fn join_conjunction(&'this self, conjunction: &str) -> String {
        let mut options = String::default();

        let mut has_at_least_two = false;
        for (item, first, last) in IterateWithFirstLast::new(self) {
            if !first {
                if last {
                    if has_at_least_two {
                        options.push_str(", ");
                    } else {
                        options.push(' ');
                    }
                    options.push_str(conjunction);
                    options.push(' ');
                } else {
                    options.push_str(", ");
                    has_at_least_two = true;
                }
            }

            options.push_str(item.as_ref());
        }

        options
    }
}