Skip to content

Commit 72a2b5e

Browse files
committed
refactor(html): DRY out create_formatter macro a bit
1 parent e4a9590 commit 72a2b5e

File tree

1 file changed

+16
-84
lines changed

1 file changed

+16
-84
lines changed

src/html.rs

Lines changed: 16 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -141,90 +141,16 @@ pub enum ChildRendering {
141141
#[macro_export]
142142
macro_rules! create_formatter {
143143
// Permit lack of trailing comma by adding one.
144-
($name:ident, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),* }) => {
145-
$crate::create_formatter!($name, { $( $pat => | $( $capture ),* | $case ),*, });
144+
($name:ident, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),* $(,)? }) => {
145+
$crate::create_formatter!(@inner $name<()>, { $( $pat => | $( $capture ),* | $case ),*, });
146146
};
147147

148-
($name:ident<$type:ty>, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),* }) => {
149-
$crate::create_formatter!($name<$type>, { $( $pat => | $( $capture ),* | $case ),*, });
148+
($name:ident<$type:ty>, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),* $(,)? }) => {
149+
$crate::create_formatter!(@inner $name<$type, $type>, { $( $pat => | $( $capture ),* | $case ),*, });
150150
};
151151

152-
($name:ident, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),*, }) => {
153-
$crate::create_formatter!($name<()>, { $( $pat => | $( $capture ),* | $case ),*, });
154-
};
155-
156-
// TODO: is there a nice way to deduplicate the below two clauses? When a
157-
// type isn't given, we default to `()`; in turn, we specialise the macro
158-
// when `()` is the type and supply the `()` value on the user's behalf.
159-
// This preserves the API from before the user type was added, and is just
160-
// neater/cleaner besides.
161-
//
162-
// If you are reading this comment, you might know of a nice way to do this!
163-
// I'd rather not resort to proc macros! TIA!
164-
($name:ident<()>, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),*, }) => {
165-
#[allow(missing_copy_implementations)]
166-
#[allow(missing_debug_implementations)]
167-
/// Created by [`comrak::create_formatter!`][crate::create_formatter].
168-
pub struct $name;
169-
170-
impl $name {
171-
/// Formats an AST as HTML, modified by the given options.
172-
#[inline]
173-
pub fn format_document<'a>(
174-
root: &'a $crate::nodes::AstNode<'a>,
175-
options: &$crate::Options,
176-
output: &mut dyn ::std::fmt::Write,
177-
) -> ::std::fmt::Result {
178-
$crate::html::format_document_with_formatter(
179-
root,
180-
options,
181-
output,
182-
&$crate::options::Plugins::default(),
183-
Self::formatter,
184-
()
185-
)
186-
}
187-
188-
/// Formats an AST as HTML, modified by the given options. Accepts custom plugins.
189-
#[inline]
190-
pub fn format_document_with_plugins<'a, 'o, 'c: 'o>(
191-
root: &'a $crate::nodes::AstNode<'a>,
192-
options: &'o $crate::Options<'c>,
193-
output: &'o mut dyn ::std::fmt::Write,
194-
plugins: &'o $crate::options::Plugins<'o>,
195-
) -> ::std::fmt::Result {
196-
$crate::html::format_document_with_formatter(
197-
root,
198-
options,
199-
output,
200-
plugins,
201-
Self::formatter,
202-
()
203-
)
204-
}
205-
206-
fn formatter<'a>(
207-
context: &mut $crate::html::Context<()>,
208-
node: &'a $crate::nodes::AstNode<'a>,
209-
entering: bool,
210-
) -> ::std::result::Result<$crate::html::ChildRendering, ::std::fmt::Error> {
211-
match node.data().value {
212-
$(
213-
$pat => {
214-
$crate::formatter_captures!((context, node, entering), ($( $capture ),*));
215-
$case
216-
// Don't warn on unconditional return in user code.
217-
#[allow(unreachable_code)]
218-
::std::result::Result::Ok($crate::html::ChildRendering::HTML)
219-
}
220-
),*
221-
_ => $crate::html::format_node_default(context, node, entering),
222-
}
223-
}
224-
}
225-
};
226-
227-
($name:ident<$type:ty>, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),*, }) => {
152+
// Actual implementation
153+
(@inner $name:ident<$type:ty $(, $user_type:ty)?>, { $( $pat:pat => | $( $capture:ident ),* | $case:tt ),* $(,)? }) => {
228154
#[allow(missing_copy_implementations)]
229155
#[allow(missing_debug_implementations)]
230156
/// Created by [`comrak::create_formatter!`][crate::create_formatter].
@@ -237,15 +163,18 @@ macro_rules! create_formatter {
237163
root: &'a $crate::nodes::AstNode<'a>,
238164
options: &$crate::Options,
239165
output: &mut dyn ::std::fmt::Write,
240-
user: $type,
166+
$(user: $user_type,)?
241167
) -> ::std::result::Result<$type, ::std::fmt::Error> {
168+
#[allow(unused_mut)]
169+
let mut maybe_user = None$(::<$user_type>)?;
170+
$(maybe_user = Some::<$user_type>(user);)?
242171
$crate::html::format_document_with_formatter(
243172
root,
244173
options,
245174
output,
246175
&$crate::options::Plugins::default(),
247176
Self::formatter,
248-
user
177+
maybe_user.unwrap_or(<$type>::default()),
249178
)
250179
}
251180

@@ -256,15 +185,18 @@ macro_rules! create_formatter {
256185
options: &'o $crate::Options<'c>,
257186
output: &'o mut dyn ::std::fmt::Write,
258187
plugins: &'o $crate::options::Plugins<'o>,
259-
user: $type,
188+
$(user: $type,)?
260189
) -> ::std::result::Result<$type, ::std::fmt::Error> {
190+
#[allow(unused_mut)]
191+
let mut maybe_user = None$(::<$user_type>)?;
192+
$(maybe_user = Some::<$user_type>(user);)?
261193
$crate::html::format_document_with_formatter(
262194
root,
263195
options,
264196
output,
265197
plugins,
266198
Self::formatter,
267-
user
199+
maybe_user.unwrap_or(<$type>::default()),
268200
)
269201
}
270202

0 commit comments

Comments
 (0)