use crate::ast::Node;
use crate::error::{WriteError, WriteResult};
use crate::options::WriterOptions;
use crate::writer::cmark::CommonMarkWriter;
use ecow::EcoString;
pub struct BlockWriterProxy<'a> {
inner: &'a mut CommonMarkWriter,
}
impl<'a> BlockWriterProxy<'a> {
pub(crate) fn new(inner: &'a mut CommonMarkWriter) -> Self {
Self { inner }
}
pub fn write_block(&mut self, node: &Node) -> WriteResult<()> {
if !node.is_block() {
return Err(WriteError::InvalidStructure(
"Block writer expected a block-level node".into(),
));
}
self.inner.write(node)
}
pub fn write_inline(&mut self, node: &Node) -> WriteResult<()> {
if node.is_block() {
return Err(WriteError::InvalidStructure(
"Inline content expected an inline node".into(),
));
}
self.inner.write(node)
}
pub fn write_inline_nodes(&mut self, nodes: &[Node]) -> WriteResult<()> {
for node in nodes {
self.write_inline(node)?;
}
Ok(())
}
pub fn write_str(&mut self, text: &str) -> WriteResult<()> {
self.inner.write_str(text)
}
pub fn write_char(&mut self, ch: char) -> WriteResult<()> {
self.inner.write_char(ch)
}
pub fn ensure_trailing_newline(&mut self) -> WriteResult<()> {
self.inner.ensure_trailing_newline()
}
pub fn ensure_blank_line(&mut self) -> WriteResult<()> {
self.inner.ensure_blank_line()
}
pub fn capture_block<F>(&mut self, f: F) -> WriteResult<EcoString>
where
F: FnOnce(&mut BlockWriterProxy<'_>) -> WriteResult<()>,
{
self.inner.capture_with_buffer(|inner| {
let mut proxy = BlockWriterProxy::new(inner);
f(&mut proxy)
})
}
pub fn capture_inline<F>(&mut self, f: F) -> WriteResult<EcoString>
where
F: FnOnce(&mut InlineWriterProxy<'_>) -> WriteResult<()>,
{
self.inner.capture_with_buffer(|inner| {
let mut proxy = InlineWriterProxy::new(inner);
f(&mut proxy)
})
}
pub fn with_temporary_options<F, R, G>(&mut self, modify: F, mut f: G) -> WriteResult<R>
where
F: FnOnce(&mut WriterOptions),
G: FnMut(&mut BlockWriterProxy<'_>) -> WriteResult<R>,
{
let original = self.inner.options.clone();
modify(&mut self.inner.options);
let result = f(self);
self.inner.options = original;
result
}
}
pub struct InlineWriterProxy<'a> {
inner: &'a mut CommonMarkWriter,
}
impl<'a> InlineWriterProxy<'a> {
pub(crate) fn new(inner: &'a mut CommonMarkWriter) -> Self {
Self { inner }
}
pub fn write_inline(&mut self, node: &Node) -> WriteResult<()> {
if node.is_block() {
return Err(WriteError::InvalidStructure(
"Inline writer cannot emit block-level nodes".into(),
));
}
self.inner.write(node)
}
pub fn write_inline_nodes(&mut self, nodes: &[Node]) -> WriteResult<()> {
for node in nodes {
self.write_inline(node)?;
}
Ok(())
}
pub fn write_str(&mut self, text: &str) -> WriteResult<()> {
self.inner.write_str(text)
}
pub fn write_char(&mut self, ch: char) -> WriteResult<()> {
self.inner.write_char(ch)
}
pub fn capture_inline<F>(&mut self, f: F) -> WriteResult<EcoString>
where
F: FnOnce(&mut InlineWriterProxy<'_>) -> WriteResult<()>,
{
self.inner.capture_with_buffer(|inner| {
let mut proxy = InlineWriterProxy::new(inner);
f(&mut proxy)
})
}
pub fn with_temporary_options<F, R, G>(&mut self, modify: F, mut f: G) -> WriteResult<R>
where
F: FnOnce(&mut WriterOptions),
G: FnMut(&mut InlineWriterProxy<'_>) -> WriteResult<R>,
{
let original = self.inner.options.clone();
modify(&mut self.inner.options);
let result = f(self);
self.inner.options = original;
result
}
}