scooby 0.5.0

An SQL query builder with a pleasant fluent API closely imitating actual SQL
Documentation
use std::fmt::{self, Display, Formatter};

pub fn joined<I, T>(iter: I, sep: &str) -> Joined<'_, I::IntoIter, T>
where
    I: IntoIterator<Item = T>,
    I::IntoIter: Clone,
    T: Display,
{
    Joined {
        iter: iter.into_iter(),
        sep,
    }
}

pub struct Joined<'a, I, T>
where
    I: Iterator<Item = T> + Clone,
    T: Display,
{
    iter: I,
    sep: &'a str,
}

impl<'a, I, T> Display for Joined<'a, I, T>
where
    I: Iterator<Item = T> + Clone,
    T: Display,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        let mut iter = self.iter.clone();

        if let Some(first) = iter.next() {
            first.fmt(f)?;
            for item in iter {
                f.write_str(self.sep)?;
                item.fmt(f)?;
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::iter::{empty, once, successors};

    #[test]
    fn no_items() {
        let iter = empty::<usize>();
        assert_eq!(joined(iter, ", ").to_string(), "");
    }

    #[test]
    fn one_item() {
        let iter = once("asdf");
        assert_eq!(joined(iter, ", ").to_string(), "asdf");
    }

    #[test]
    fn two_items() {
        let iter = successors(Some(0), |x| Some(x + 1)).take(2);
        assert_eq!(joined(iter, ", ").to_string(), "0, 1");
    }

    #[test]
    fn a_few_items() {
        let iter = successors(Some(0), |x| Some(x + 1)).take(10);
        assert_eq!(
            joined(iter, ", ").to_string(),
            "0, 1, 2, 3, 4, 5, 6, 7, 8, 9"
        );
    }
}