use crate::pretty::{PrettyPrinter, prelude::*};
pub struct FlowItem<'a>(pub Option<FlowItemRepr<'a>>);
pub struct FlowItemRepr<'a> {
pub doc: ArenaDoc<'a>,
pub space_before: bool,
pub space_after: bool,
}
impl<'a> FlowItem<'a> {
pub fn new(doc: ArenaDoc<'a>, space_before: bool, space_after: bool) -> Self {
Self(Some(FlowItemRepr {
doc,
space_before,
space_after,
}))
}
pub fn spaced(doc: ArenaDoc<'a>) -> Self {
Self::new(doc, true, true)
}
pub fn spaced_before(doc: ArenaDoc<'a>, space_after: bool) -> Self {
Self::new(doc, true, space_after)
}
pub fn tight_spaced(doc: ArenaDoc<'a>) -> Self {
Self::new(doc, false, true)
}
pub fn spaced_tight(doc: ArenaDoc<'a>) -> Self {
Self::new(doc, true, false)
}
pub fn tight(doc: ArenaDoc<'a>) -> Self {
Self::new(doc, false, false)
}
pub const fn none() -> Self {
Self(None)
}
}
pub struct FlowStylist<'a> {
printer: &'a PrettyPrinter<'a>,
doc: ArenaDoc<'a>,
space_after: bool,
at_line_start: bool,
}
impl<'a> FlowStylist<'a> {
pub fn new(printer: &'a PrettyPrinter<'a>) -> Self {
Self {
doc: printer.arena.nil(),
printer,
space_after: false,
at_line_start: true,
}
}
pub fn push_comment(&mut self, doc: ArenaDoc<'a>, is_block: bool) {
if is_block {
self.push_doc(doc, true, true);
} else {
if !self.at_line_start {
self.space_after = true;
}
self.push_doc(doc, true, false);
}
}
pub fn push_doc(&mut self, doc: ArenaDoc<'a>, space_before: bool, space_after: bool) {
if space_before && self.space_after {
self.doc += self.printer.arena.space();
}
self.doc += doc;
self.space_after = space_after;
self.at_line_start = false;
}
pub fn enter_new_line(&mut self) {
self.at_line_start = true;
}
pub fn into_doc(self) -> ArenaDoc<'a> {
self.doc
}
}