cmark_writer/writer/runtime/
proxy.rs1use crate::ast::Node;
2use crate::error::{WriteError, WriteResult};
3use crate::options::WriterOptions;
4use crate::writer::cmark::CommonMarkWriter;
5use ecow::EcoString;
6
7pub struct BlockWriterProxy<'a> {
9 inner: &'a mut CommonMarkWriter,
10}
11
12impl<'a> BlockWriterProxy<'a> {
13 pub(crate) fn new(inner: &'a mut CommonMarkWriter) -> Self {
14 Self { inner }
15 }
16
17 pub fn write_block(&mut self, node: &Node) -> WriteResult<()> {
19 if !node.is_block() {
20 return Err(WriteError::InvalidStructure(
21 "Block writer expected a block-level node".into(),
22 ));
23 }
24 self.inner.write(node)
25 }
26
27 pub fn write_inline(&mut self, node: &Node) -> WriteResult<()> {
29 if node.is_block() {
30 return Err(WriteError::InvalidStructure(
31 "Inline content expected an inline node".into(),
32 ));
33 }
34 self.inner.write(node)
35 }
36
37 pub fn write_inline_nodes(&mut self, nodes: &[Node]) -> WriteResult<()> {
39 for node in nodes {
40 self.write_inline(node)?;
41 }
42 Ok(())
43 }
44
45 pub fn write_str(&mut self, text: &str) -> WriteResult<()> {
47 self.inner.write_str(text)
48 }
49
50 pub fn write_char(&mut self, ch: char) -> WriteResult<()> {
52 self.inner.write_char(ch)
53 }
54
55 pub fn ensure_trailing_newline(&mut self) -> WriteResult<()> {
57 self.inner.ensure_trailing_newline()
58 }
59
60 pub fn ensure_blank_line(&mut self) -> WriteResult<()> {
62 self.inner.ensure_blank_line()
63 }
64
65 pub fn capture_block<F>(&mut self, f: F) -> WriteResult<EcoString>
67 where
68 F: FnOnce(&mut BlockWriterProxy<'_>) -> WriteResult<()>,
69 {
70 self.inner.capture_with_buffer(|inner| {
71 let mut proxy = BlockWriterProxy::new(inner);
72 f(&mut proxy)
73 })
74 }
75
76 pub fn capture_inline<F>(&mut self, f: F) -> WriteResult<EcoString>
78 where
79 F: FnOnce(&mut InlineWriterProxy<'_>) -> WriteResult<()>,
80 {
81 self.inner.capture_with_buffer(|inner| {
82 let mut proxy = InlineWriterProxy::new(inner);
83 f(&mut proxy)
84 })
85 }
86
87 pub fn with_temporary_options<F, R, G>(&mut self, modify: F, mut f: G) -> WriteResult<R>
89 where
90 F: FnOnce(&mut WriterOptions),
91 G: FnMut(&mut BlockWriterProxy<'_>) -> WriteResult<R>,
92 {
93 let original = self.inner.options.clone();
94 modify(&mut self.inner.options);
95 let result = f(self);
96 self.inner.options = original;
97 result
98 }
99}
100
101pub struct InlineWriterProxy<'a> {
103 inner: &'a mut CommonMarkWriter,
104}
105
106impl<'a> InlineWriterProxy<'a> {
107 pub(crate) fn new(inner: &'a mut CommonMarkWriter) -> Self {
108 Self { inner }
109 }
110
111 pub fn write_inline(&mut self, node: &Node) -> WriteResult<()> {
113 if node.is_block() {
114 return Err(WriteError::InvalidStructure(
115 "Inline writer cannot emit block-level nodes".into(),
116 ));
117 }
118 self.inner.write(node)
119 }
120
121 pub fn write_inline_nodes(&mut self, nodes: &[Node]) -> WriteResult<()> {
123 for node in nodes {
124 self.write_inline(node)?;
125 }
126 Ok(())
127 }
128
129 pub fn write_str(&mut self, text: &str) -> WriteResult<()> {
131 self.inner.write_str(text)
132 }
133
134 pub fn write_char(&mut self, ch: char) -> WriteResult<()> {
136 self.inner.write_char(ch)
137 }
138
139 pub fn capture_inline<F>(&mut self, f: F) -> WriteResult<EcoString>
141 where
142 F: FnOnce(&mut InlineWriterProxy<'_>) -> WriteResult<()>,
143 {
144 self.inner.capture_with_buffer(|inner| {
145 let mut proxy = InlineWriterProxy::new(inner);
146 f(&mut proxy)
147 })
148 }
149
150 pub fn with_temporary_options<F, R, G>(&mut self, modify: F, mut f: G) -> WriteResult<R>
152 where
153 F: FnOnce(&mut WriterOptions),
154 G: FnMut(&mut InlineWriterProxy<'_>) -> WriteResult<R>,
155 {
156 let original = self.inner.options.clone();
157 modify(&mut self.inner.options);
158 let result = f(self);
159 self.inner.options = original;
160 result
161 }
162}