use crate::buffer::BufferSnapshot;
use crate::builders::{FillBuilder, JoinBuilder};
use crate::prelude::*;
use crate::{Arguments, Buffer, FormatContext, FormatState, GroupId, VecBuffer};
pub struct Formatter<'buf, Context> {
pub(super) buffer: &'buf mut dyn Buffer<Context = Context>,
}
impl<'buf, Context> Formatter<'buf, Context> {
pub fn new(buffer: &'buf mut (dyn Buffer<Context = Context> + 'buf)) -> Self {
Self { buffer }
}
pub fn options(&self) -> &Context::Options
where
Context: FormatContext,
{
self.context().options()
}
pub fn context(&self) -> &Context {
self.state().context()
}
pub fn context_mut(&mut self) -> &mut Context {
self.state_mut().context_mut()
}
pub fn group_id(&self, debug_name: &'static str) -> GroupId {
self.state().group_id(debug_name)
}
pub fn join<'a>(&'a mut self) -> JoinBuilder<'a, 'buf, (), Context> {
JoinBuilder::new(self)
}
pub fn join_with<'a, Joiner>(
&'a mut self,
joiner: Joiner,
) -> JoinBuilder<'a, 'buf, Joiner, Context>
where
Joiner: Format<Context>,
{
JoinBuilder::with_separator(self, joiner)
}
pub fn fill<'a>(&'a mut self) -> FillBuilder<'a, 'buf, Context> {
FillBuilder::new(self)
}
pub fn intern(&mut self, content: &dyn Format<Context>) -> FormatResult<Option<FormatElement>> {
let mut buffer = VecBuffer::new(self.state_mut());
crate::write!(&mut buffer, [content])?;
let elements = buffer.into_vec();
Ok(self.intern_vec(elements))
}
pub fn intern_vec(&mut self, mut elements: Vec<FormatElement>) -> Option<FormatElement> {
match elements.len() {
0 => None,
1 => Some(elements.pop().unwrap()),
_ => Some(FormatElement::Interned(Interned::new(elements))),
}
}
}
impl<Context> Formatter<'_, Context>
where
Context: FormatContext,
{
#[inline]
pub fn state_snapshot(&self) -> FormatterSnapshot {
FormatterSnapshot {
buffer: self.buffer.snapshot(),
}
}
#[inline]
pub fn restore_state_snapshot(&mut self, snapshot: FormatterSnapshot) {
self.buffer.restore_snapshot(snapshot.buffer);
}
}
impl<Context> Buffer for Formatter<'_, Context> {
type Context = Context;
#[inline]
fn write_element(&mut self, element: FormatElement) {
self.buffer.write_element(element);
}
fn elements(&self) -> &[FormatElement] {
self.buffer.elements()
}
#[inline]
fn write_fmt(&mut self, arguments: Arguments<Self::Context>) -> FormatResult<()> {
for argument in arguments.items() {
argument.format(self)?;
}
Ok(())
}
fn state(&self) -> &FormatState<Self::Context> {
self.buffer.state()
}
fn state_mut(&mut self) -> &mut FormatState<Self::Context> {
self.buffer.state_mut()
}
fn snapshot(&self) -> BufferSnapshot {
self.buffer.snapshot()
}
fn restore_snapshot(&mut self, snapshot: BufferSnapshot) {
self.buffer.restore_snapshot(snapshot);
}
}
pub struct FormatterSnapshot {
buffer: BufferSnapshot,
}