use core::fmt;
pub mod op;
use crate::{
context::Context,
printable::{ListSeparator, Printable, State},
};
struct PrinterFn<F>(F);
impl<F> Printable for PrinterFn<F>
where
F: Fn(&Context, &State, &mut fmt::Formatter<'_>) -> fmt::Result,
{
fn fmt(&self, ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(self.0)(ctx, state, f)
}
}
pub fn printable_from_fn<F>(print: F) -> impl Printable
where
F: Fn(&Context, &State, &mut fmt::Formatter<'_>) -> fmt::Result,
{
PrinterFn(print)
}
pub fn quoted(s: &str) -> impl Printable + '_ {
printable_from_fn(
move |_ctx: &Context, _state: &State, f: &mut fmt::Formatter<'_>| write!(f, "{s:?}"),
)
}
pub fn list_with_sep<T: Printable>(items: &[T], sep: ListSeparator) -> impl Printable + '_ {
iter_with_sep(items.iter(), sep)
}
pub fn iter_with_sep<I>(iter: I, sep: ListSeparator) -> impl Printable
where
I: Iterator + Clone,
I::Item: Printable,
{
iter_with_sep_by(iter, sep, |item, ctx, state, f| item.fmt(ctx, state, f))
}
pub fn iter_with_sep_by<I, F>(iter: I, sep: ListSeparator, print_item: F) -> impl Printable
where
I: Iterator + Clone,
F: Fn(I::Item, &Context, &State, &mut fmt::Formatter<'_>) -> fmt::Result,
{
printable_from_fn(
move |ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>| {
let mut iter = iter.clone();
if let Some(first) = iter.next() {
print_item(first, ctx, state, f)?;
}
for item in iter {
sep.fmt(ctx, state, f)?;
print_item(item, ctx, state, f)?;
}
Ok(())
},
)
}
pub fn enclosed<P: Printable>(left: &'static str, right: &'static str, p: P) -> impl Printable {
printable_from_fn(
move |ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>| {
write!(f, "{left}")?;
p.fmt(ctx, state, f)?;
write!(f, "{right}")
},
)
}