use std::{
fmt::{self, Write},
ops::{Deref, RangeBounds},
};
#[derive(Debug)]
pub struct Buffer {
inner: String,
indentation: String,
}
impl Buffer {
pub(crate) fn with_capacity(capacity: usize) -> Self {
Self {
inner: String::with_capacity(capacity),
indentation: String::new(),
}
}
pub(crate) fn len(&self) -> usize {
self.inner.len()
}
pub(crate) fn replace_range<R: RangeBounds<usize>>(&mut self, range: R, replace_with: &str) {
self.inner.replace_range(range, replace_with);
}
pub fn is_unindented(&mut self) -> bool {
self.indentation.is_empty()
}
pub fn indent(&mut self) {
let _ = write!(self.indentation, " ");
}
pub fn unindent(&mut self) {
self.indentation.truncate(self.indentation.len() - 2);
}
pub fn line<T: fmt::Display>(&mut self, val: T) {
writeln!(self.inner, "{}{}", self.indentation, val)
.expect("writing to a String can't fail");
}
pub fn lines<T: fmt::Display>(&mut self, lines: impl IntoIterator<Item = T>) {
lines.into_iter().for_each(|l| {
writeln!(self.inner, "{}{}", self.indentation, l)
.expect("writing to a String can't fail");
});
}
pub fn raw(&mut self, raw: &str) {
self.inner.push_str(raw);
}
pub fn into_inner(self) -> String {
self.inner
}
}
impl Deref for Buffer {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.inner
}
}