use core::fmt::*;
use crate::once::Once;
pub(crate) mod types {
#[allow(unused)]
use super::*;
#[derive(Clone, Copy)]
pub struct Join<I, S> {
pub(super) iter: I,
pub(super) sep: S,
}
pub type JoinOnce<I, S> = Join<Once<I>, S>;
#[derive(Clone, Copy)]
pub struct JoinMap<I, S, F> {
pub(super) iter: I,
pub(super) sep: S,
pub(super) map: F,
}
pub type JoinMapOnce<I, S, F> = JoinMap<Once<I>, S, F>;
#[derive(Clone, Copy)]
pub struct JoinTuple<T, S> {
pub(super) tuple: T,
pub(super) sep: S,
}
pub type Csv<I> = Join<I, &'static str>;
pub type CsvOnce<I> = Csv<Once<I>>;
pub type CsvMap<I, F> = JoinMap<I, &'static str, F>;
pub type CsvMapOnce<I, F> = CsvMap<Once<I>, F>;
pub type CsvTuple<T> = JoinTuple<T, &'static str>;
}
use types::*;
pub fn join<I, S>(iter: I, sep: S) -> Join<I::IntoIter, S>
where
I: IntoIterator,
I::IntoIter: Clone,
{
Join { iter: iter.into_iter(), sep }
}
pub fn join_once<I, S>(iter: I, sep: S) -> JoinOnce<I::IntoIter, S>
where
I: IntoIterator,
{
Join { iter: Once::new(iter.into_iter()), sep }
}
pub fn join_map<I, S, R, F>(iter: I, sep: S, f: F) -> JoinMap<I::IntoIter, S, F>
where
I: IntoIterator,
I::IntoIter: Clone,
F: Fn(I::Item) -> R,
{
JoinMap { iter: iter.into_iter(), sep, map: f }
}
pub fn join_map_once<I, S, R, F>(
iter: I,
sep: S,
f: F,
) -> JoinMapOnce<I::IntoIter, S, F>
where
I: IntoIterator,
F: Fn(I::Item) -> R,
{
JoinMap { iter: Once::new(iter.into_iter()), sep, map: f }
}
pub fn join_tuple<T, S>(tuple: T, sep: S) -> JoinTuple<T, S> {
JoinTuple { tuple, sep }
}
pub fn csv<I>(iter: I) -> Csv<I::IntoIter>
where
I: IntoIterator,
I::IntoIter: Clone,
{
join(iter, ", ")
}
pub fn csv_once<I>(iter: I) -> CsvOnce<I::IntoIter>
where
I: IntoIterator,
{
join_once(iter, ", ")
}
pub fn csv_map<I, R, F>(iter: I, f: F) -> CsvMap<I::IntoIter, F>
where
I: IntoIterator,
I::IntoIter: Clone,
F: Fn(I::Item) -> R,
{
join_map(iter, ", ", f)
}
pub fn csv_map_once<I, R, F>(iter: I, f: F) -> CsvMapOnce<I::IntoIter, F>
where
I: IntoIterator,
F: Fn(I::Item) -> R,
{
join_map_once(iter, ", ", f)
}
pub fn csv_tuple<T>(tuple: T) -> CsvTuple<T> {
join_tuple(tuple, ", ")
}
impl<I, S> Debug for Join<I, S>
where
I: Iterator + Clone,
I::Item: Debug,
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
let mut iter = self.iter.clone();
if let Some(item) = iter.next() {
write!(f, "{:?}", item)?;
}
for item in iter {
write!(f, "{}{:?}", self.sep, item)?;
}
Ok(())
}
}
impl<I, S> Display for Join<I, S>
where
I: Iterator + Clone,
I::Item: Display,
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
let mut iter = self.iter.clone();
if let Some(item) = iter.next() {
write!(f, "{}", item)?;
}
for item in iter {
write!(f, "{}{}", self.sep, item)?;
}
Ok(())
}
}
impl<I, S> Debug for JoinOnce<I, S>
where
I: Iterator,
I::Item: Debug,
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
if let Some(mut iter) = self.iter.take() {
if let Some(item) = iter.next() {
write!(f, "{:?}", item)?;
}
for item in iter {
write!(f, "{}{:?}", self.sep, item)?;
}
}
Ok(())
}
}
impl<I, S> Display for JoinOnce<I, S>
where
I: Iterator,
I::Item: Display,
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
if let Some(mut iter) = self.iter.take() {
if let Some(item) = iter.next() {
write!(f, "{}", item)?;
}
for item in iter {
write!(f, "{}{}", self.sep, item)?;
}
}
Ok(())
}
}
impl<I, S, F, R> Debug for JoinMap<I, S, F>
where
I: Iterator + Clone,
S: Display,
F: Fn(I::Item) -> R,
R: Debug,
{
fn fmt(&self, f: &mut Formatter) -> Result {
let mut iter = self.iter.clone();
if let Some(item) = iter.next() {
write!(f, "{:?}", (self.map)(item))?;
}
for item in iter {
write!(f, "{}{:?}", self.sep, (self.map)(item))?;
}
Ok(())
}
}
impl<I, S, F, R> Display for JoinMap<I, S, F>
where
I: Iterator + Clone,
S: Display,
F: Fn(I::Item) -> R,
R: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
let mut iter = self.iter.clone();
if let Some(item) = iter.next() {
write!(f, "{}", (self.map)(item))?;
}
for item in iter {
write!(f, "{}{}", self.sep, (self.map)(item))?;
}
Ok(())
}
}
impl<I, S, F, R> Debug for JoinMapOnce<I, S, F>
where
I: Iterator,
S: Display,
F: Fn(I::Item) -> R,
R: Debug,
{
fn fmt(&self, f: &mut Formatter) -> Result {
if let Some(mut iter) = self.iter.take() {
if let Some(item) = iter.next() {
write!(f, "{:?}", (self.map)(item))?;
}
for item in iter {
write!(f, "{}{:?}", self.sep, (self.map)(item))?;
}
}
Ok(())
}
}
impl<I, S, F, R> Display for JoinMapOnce<I, S, F>
where
I: Iterator,
S: Display,
F: Fn(I::Item) -> R,
R: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
if let Some(mut iter) = self.iter.take() {
if let Some(item) = iter.next() {
write!(f, "{}", (self.map)(item))?;
}
for item in iter {
write!(f, "{}{}", self.sep, (self.map)(item))?;
}
}
Ok(())
}
}
impl<S: Display> Debug for JoinTuple<(), S> {
fn fmt(&self, _: &mut Formatter) -> Result {
Ok(())
}
}
impl<S: Display> Display for JoinTuple<(), S> {
fn fmt(&self, _: &mut Formatter) -> Result {
Ok(())
}
}
impl<T0: Debug, S: Display> Debug for JoinTuple<(T0,), S> {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{:?}", self.tuple.0)
}
}
impl<T0: Display, S: Display> Display for JoinTuple<(T0,), S> {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{}", self.tuple.0)
}
}
macro_rules! impl_tuple {
($x:ident) => {};
($($x:ident),+) => {
impl<$($x),+, S> Debug for JoinTuple<($($x,)+), S>
where
$($x: Debug,)+
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
#[allow(non_snake_case)]
let ($($x,)+) = &self.tuple;
write!(
f,
impl_tuple_fmt_debug!($($x),+),
$($x = $x,)+
sep = self.sep,
)
}
}
impl<$($x),+, S> Display for JoinTuple<($($x,)+), S>
where
$($x: Display,)+
S: Display,
{
fn fmt(&self, f: &mut Formatter) -> Result {
#[allow(non_snake_case)]
let ($($x,)+) = &self.tuple;
write!(
f,
impl_tuple_fmt_display!($($x),+),
$($x = $x,)+
sep = self.sep,
)
}
}
peel!(impl_tuple: $($x),+);
};
}
macro_rules! impl_tuple_fmt_debug {
($x:ident $(, $rest:ident)*) => {
core::concat!(
"{", core::stringify!($x), ":?}",
$("{sep}{", core::stringify!($rest), ":?}",)*
)
};
}
macro_rules! impl_tuple_fmt_display {
($x:ident $(, $rest:ident)*) => {
core::concat!(
"{", core::stringify!($x), "}",
$("{sep}{", core::stringify!($rest), "}",)*
)
};
}
impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);