use crate::PrettyPrint;
use alloc::borrow::Cow;
use core::fmt::{Debug, Formatter};
use pretty::{
termcolor::{Color, ColorSpec},
Arena, DocAllocator, DocBuilder, Pretty,
};
pub type PrettyTree<'a> = DocBuilder<'a, Arena<'a, ColorSpec>, ColorSpec>;
pub struct PrettyProvider<'a> {
arena: Arena<'a, ColorSpec>,
keyword: ColorSpec,
}
impl<'a> Debug for PrettyProvider<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PrettyProvider").finish()
}
}
impl<'a> PrettyProvider<'a> {
pub fn new() -> Self {
PrettyProvider { arena: Arena::new(), keyword: ColorSpec::new().set_fg(Some(Color::Rgb(197, 119, 207))).clone() }
}
}
impl<'a> PrettyProvider<'a>
where
'a: 'static,
{
pub fn nil(&'a self) -> PrettyTree<'a> {
self.arena.nil()
}
pub fn space(&'a self) -> PrettyTree<'a> {
self.arena.space()
}
pub fn hardline(&'a self) -> PrettyTree<'a> {
self.arena.hardline()
}
pub fn text<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
self.arena.text(text)
}
pub fn keyword<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
self.text(text.into()).annotate(self.keyword.clone())
}
pub fn identifier<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
self.operator(text)
}
pub fn generic<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
self.text(text.into()).annotate(self.macro_style())
}
pub fn argument<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
let kw = ColorSpec::new().set_fg(Some(Color::Rgb(239, 112, 117))).clone();
self.text(text.into()).annotate(kw)
}
pub fn operator<S>(&'a self, text: S) -> PrettyTree<'a>
where
S: Into<Cow<'static, str>>,
{
let kw = ColorSpec::new().set_fg(Some(Color::Rgb(90, 173, 238))).clone();
self.text(text.into()).annotate(kw)
}
pub fn string_style(&self) -> ColorSpec {
ColorSpec::new().set_fg(Some(Color::Rgb(152, 195, 121))).clone()
}
pub fn number_style(&self) -> ColorSpec {
ColorSpec::new().set_fg(Some(Color::Rgb(206, 153, 100))).clone()
}
pub fn macro_style(&self) -> ColorSpec {
ColorSpec::new().set_fg(Some(Color::Rgb(87, 182, 194))).clone()
}
}
impl<'a> PrettyProvider<'a> {
#[inline]
pub fn concat<I>(&'a self, docs: I) -> PrettyTree<'a>
where
I: IntoIterator,
I::Item: Pretty<'a, Arena<'a, ColorSpec>, ColorSpec>,
{
self.arena.concat(docs)
}
#[inline]
pub fn intersperse<T, S>(&'a self, terms: &[T], joint: S) -> PrettyTree<'a>
where
T: PrettyPrint,
S: Pretty<'a, Arena<'a, ColorSpec>, ColorSpec> + Clone,
{
self.arena.intersperse(terms.iter().map(|x| x.build(self)), joint)
}
#[inline]
pub fn join<T, S>(&'a self, terms: &[T], joint: &'static str) -> PrettyTree<'a>
where
T: PrettyPrint,
S: Pretty<'a, Arena<'a, ColorSpec>, ColorSpec> + Clone,
{
self.arena.intersperse(terms.iter().map(|x| x.build(self)), self.arena.text(joint))
}
}