Skip to main content

hax_rust_engine/printer/pretty_ast/
to_document.rs

1use pretty::{BoxAllocator, DocAllocator};
2use std::ops::Deref as _;
3
4/// A convenience alias tying the document builder to the global
5/// [`pretty::BoxAllocator`].
6pub type DocBuilder<A> = pretty::DocBuilder<'static, BoxAllocator, A>;
7
8/// Convert a value into a document by-value.
9///
10/// Implementations typically delegate to [`ToDocument`] after adjusting the
11/// input ownership (e.g., cloning or borrowing). It allows helpers to accept
12/// either borrowed or owned values transparently.
13pub trait ToDocumentOwned<P, A> {
14    /// Produce a document using the provided printer.
15    fn to_document_owned(self, printer: &P) -> DocBuilder<A>;
16}
17
18impl<P, A, T: ToDocument<P, A>> ToDocumentOwned<P, A> for &T {
19    fn to_document_owned(self, printer: &P) -> DocBuilder<A> {
20        self.to_document(printer)
21    }
22}
23
24impl<P, A> ToDocumentOwned<P, A> for DocBuilder<A> {
25    fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
26        self
27    }
28}
29impl<P, A> ToDocumentOwned<P, A> for &str {
30    fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
31        DocAllocator::as_string(&BoxAllocator, self)
32    }
33}
34impl<P, A> ToDocumentOwned<P, A> for String {
35    fn to_document_owned(self, _printer: &P) -> DocBuilder<A> {
36        DocAllocator::as_string(&BoxAllocator, self)
37    }
38}
39impl<P, A> ToDocumentOwned<P, A> for Option<&str> {
40    fn to_document_owned(self, printer: &P) -> DocBuilder<A> {
41        self.map(|s| s.to_document_owned(printer))
42            .unwrap_or_else(|| DocAllocator::nil(&BoxAllocator))
43    }
44}
45
46/// Convert a value into a document using the supplied printer.
47///
48/// This is the primary trait invoked throughout the pretty-printing pipeline;
49/// it mirrors [`pretty::Pretty::pretty`] while giving access to printer-specific
50/// context.
51pub trait ToDocument<P: ?Sized, A> {
52    /// Produce a document using the provided printer reference.
53    fn to_document(&self, printer: &P) -> DocBuilder<A>;
54}
55
56impl<A, P, T: ToDocument<P, A>> ToDocument<P, A> for Box<T> {
57    fn to_document(&self, printer: &P) -> DocBuilder<A> {
58        self.deref().to_document(printer)
59    }
60}
61impl<A, P, T: ToDocument<P, A>> ToDocument<P, A> for Option<T> {
62    fn to_document(&self, printer: &P) -> DocBuilder<A> {
63        self.as_ref()
64            .map(|value| value.to_document(printer))
65            .unwrap_or_else(|| DocAllocator::nil(&BoxAllocator))
66    }
67}
68impl<A, P> ToDocument<P, A> for String {
69    fn to_document(&self, _printer: &P) -> DocBuilder<A> {
70        DocAllocator::as_string(&BoxAllocator, self)
71    }
72}
73impl<A: Clone, P> ToDocument<P, A> for DocBuilder<A> {
74    #[inline(always)]
75    fn to_document(&self, _printer: &P) -> DocBuilder<A> {
76        self.clone()
77    }
78}
79impl<A: Clone, P, T> ToDocument<P, A> for &T
80where
81    T: ToDocument<P, A>,
82{
83    #[inline(always)]
84    fn to_document(&self, printer: &P) -> DocBuilder<A> {
85        (*self).to_document(printer)
86    }
87}