use std::fmt;
pub mod op;
use crate::{
context::Context,
printable::{ListSeparator, Printable, State, fmt_iter},
};
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 disp(disp: impl fmt::Display) -> impl Printable {
PrinterFn(move |_ctx: &Context, _state: &State, f: &mut fmt::Formatter<'_>| write!(f, "{disp}"))
}
pub fn quoted(s: &str) -> impl Printable + '_ {
PrinterFn(move |_ctx: &Context, _state: &State, f: &mut fmt::Formatter<'_>| write!(f, "{s:?}"))
}
pub fn formatted(s: String) -> impl Printable {
PrinterFn(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,
{
PrinterFn(
move |ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>| {
fmt_iter(iter.clone(), ctx, state, sep, f)
},
)
}
pub fn enclosed<P: Printable>(left: &'static str, right: &'static str, p: P) -> impl Printable {
PrinterFn(
move |ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>| {
write!(f, "{left}")?;
p.fmt(ctx, state, f)?;
write!(f, "{right}")
},
)
}
pub fn functional_type<'a>(
inputs: impl Printable + 'a,
results: impl Printable + 'a,
) -> impl Printable + 'a {
PrinterFn(
move |ctx: &Context, state: &State, f: &mut fmt::Formatter<'_>| {
write!(
f,
"<({}) -> ({})>",
inputs.print(ctx, state),
results.print(ctx, state)
)
},
)
}