use pretty::{BoxAllocator, DocAllocator};
use std::ops::Deref as _;
pub type DocBuilder<A> = pretty::DocBuilder<'static, BoxAllocator, A>;
pub trait ToDocumentOwned<P, A> {
fn to_document_owned(self, printer: &P) -> DocBuilder<A>;
}
impl<P, A, T: ToDocument<P, A>> ToDocumentOwned<P, A> for &T {
fn to_document_owned(self, printer: &P) -> DocBuilder<A> {
self.to_document(printer)
}
}
impl<P, A> ToDocumentOwned<P, A> for DocBuilder<A> {
fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
self
}
}
impl<P, A> ToDocumentOwned<P, A> for &str {
fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
DocAllocator::as_string(&BoxAllocator, self)
}
}
impl<P, A> ToDocumentOwned<P, A> for String {
fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
DocAllocator::as_string(&BoxAllocator, self)
}
}
impl<P, A> ToDocumentOwned<P, A> for Option<&str> {
fn to_document_owned(self, printer: &P) -> DocBuilder<A> {
self.map(|s| s.to_document_owned(printer))
.unwrap_or_else(|| DocAllocator::nil(&BoxAllocator))
}
}
pub trait ToDocument<P: ?Sized, A> {
fn to_document(&self, printer: &P) -> DocBuilder<A>;
}
impl<A, P, T: ToDocument<P, A>> ToDocument<P, A> for Box<T> {
fn to_document(&self, printer: &P) -> DocBuilder<A> {
self.deref().to_document(printer)
}
}
impl<A, P, T: ToDocument<P, A>> ToDocument<P, A> for Option<T> {
fn to_document(&self, printer: &P) -> DocBuilder<A> {
self.as_ref()
.map(|value| value.to_document(printer))
.unwrap_or_else(|| DocAllocator::nil(&BoxAllocator))
}
}
impl<A, P> ToDocument<P, A> for String {
fn to_document(&self, _printer: &P) -> DocBuilder<A> {
DocAllocator::as_string(&BoxAllocator, self)
}
}
impl<A: Clone, P> ToDocument<P, A> for DocBuilder<A> {
#[inline(always)]
fn to_document(&self, _printer: &P) -> DocBuilder<A> {
self.clone()
}
}
impl<A: Clone, P, T> ToDocument<P, A> for &T
where
T: ToDocument<P, A>,
{
#[inline(always)]
fn to_document(&self, printer: &P) -> DocBuilder<A> {
(*self).to_document(printer)
}
}