use super::{Doc, Elem, Emit, GroupKind, Spacing, TextKind};
impl Doc {
fn text_with(&mut self, ann: TextKind, s: impl Into<String>) -> &mut Self {
let s = s.into();
if !s.is_empty() {
self.0.push(Elem::Text(0, 0, ann, s));
}
self
}
pub fn text(&mut self, s: impl Into<String>) -> &mut Self {
self.text_with(TextKind::Regular, s)
}
pub fn comment(&mut self, s: impl Into<String>) -> &mut Self {
self.text_with(TextKind::Comment, s)
}
pub fn trailing_comment(&mut self, s: impl Into<String>) -> &mut Self {
self.text_with(TextKind::TrailingComment, s)
}
pub fn trailing(&mut self, s: impl Into<String>) -> &mut Self {
self.text_with(TextKind::Trailing, s)
}
pub fn group(&mut self, f: impl FnOnce(&mut Self)) -> &mut Self {
self.group_with(GroupKind::Regular, f)
}
pub fn priority_group(&mut self, f: impl FnOnce(&mut Self)) -> &mut Self {
self.group_with(GroupKind::Priority, f)
}
pub fn transparent_group(&mut self, f: impl FnOnce(&mut Self)) -> &mut Self {
self.group_with(GroupKind::Transparent, f)
}
pub fn group_with(&mut self, kind: GroupKind, f: impl FnOnce(&mut Self)) -> &mut Self {
let start = self.0.len();
f(self);
let inner = Self(self.0.split_off(start));
self.0.push(Elem::Group(kind, inner));
self
}
fn nest_pair(&mut self, dn: isize, doff: isize, f: impl FnOnce(&mut Self)) -> &mut Self {
self.0.push(Elem::Nest(dn, doff));
f(self);
self.0.push(Elem::Nest(-dn, -doff));
self
}
pub fn nested(&mut self, f: impl FnOnce(&mut Self)) -> &mut Self {
self.nest_pair(1, 0, f)
}
pub fn offset(&mut self, level: usize, f: impl FnOnce(&mut Self)) -> &mut Self {
self.nest_pair(0, level.cast_signed(), f)
}
pub fn sep_by<P: Emit>(
&mut self,
separator: &[Elem],
items: impl IntoIterator<Item = P>,
) -> &mut Self {
let mut first = true;
for item in items {
if !first {
self.0.extend_from_slice(separator);
}
first = false;
item.emit(self);
}
self
}
pub fn surrounded(&mut self, outside: &[Elem], f: impl FnOnce(&mut Self)) -> &mut Self {
self.0.extend_from_slice(outside);
f(self);
self.0.extend_from_slice(outside);
self
}
pub fn softbreak(&mut self) -> &mut Self {
self.push_raw(Elem::Spacing(Spacing::Softbreak))
}
pub fn linebreak(&mut self) -> &mut Self {
self.push_raw(linebreak())
}
pub fn softline(&mut self) -> &mut Self {
self.push_raw(Elem::Spacing(Spacing::Softspace))
}
pub fn line(&mut self) -> &mut Self {
self.push_raw(line())
}
pub fn hardspace(&mut self) -> &mut Self {
self.push_raw(hardspace())
}
pub fn hardline(&mut self) -> &mut Self {
self.push_raw(hardline())
}
pub fn emptyline(&mut self) -> &mut Self {
self.push_raw(Elem::Spacing(Spacing::Emptyline))
}
}
pub const fn linebreak() -> Elem {
Elem::Spacing(Spacing::Break)
}
pub const fn line() -> Elem {
Elem::Spacing(Spacing::Space)
}
pub const fn hardspace() -> Elem {
Elem::Spacing(Spacing::Hardspace)
}
pub const fn hardline() -> Elem {
Elem::Spacing(Spacing::Hardline)
}
pub const fn newline() -> Elem {
Elem::Spacing(Spacing::Newlines(1))
}