Skip to content

Commit 1fcdd9d

Browse files
committed
Change the Postprocessor type from an alias to a trait
This creates a parallel EmbedPostprocessor trait, and it adds new methods for registering trait objects into the postprocessor chains. The trait is implemented for the callback Fn type that was previously declared as the Postprocessor type.
1 parent 7988b21 commit 1fcdd9d

File tree

2 files changed

+54
-48
lines changed

2 files changed

+54
-48
lines changed

src/lib.rs

+51-45
Original file line numberDiff line numberDiff line change
@@ -133,26 +133,45 @@ pub type MarkdownEvents<'a> = Vec<Event<'a>>;
133133
/// # exporter.run().unwrap();
134134
/// ```
135135
136-
pub type Postprocessor<'f> =
137-
dyn Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult + Send + Sync + 'f;
138136
type Result<T, E = ExportError> = std::result::Result<T, E>;
139137

140-
/// Postprocess is a trait form of the [Postprocessor] callback that can be passed to
141-
/// [Exporter::add_postprocessor_impl].
142-
pub trait Postprocess: Send + Sync {
138+
/// Postprocessor that can be that can be passed to [Exporter::add_postprocessor_impl].
139+
pub trait Postprocessor: Send + Sync {
143140
fn postprocess(&self, ctx: &mut Context, events: &mut MarkdownEvents) -> PostprocessorResult;
144141
}
145142

146-
/// EmbedPostprocess is a trait form of the [Postprocessor] callback that can be
147-
/// passed to [Exporter::add_embed_postprocessor_impl].
148-
pub trait EmbedPostprocess: Send + Sync {
143+
/// Postprocessor is implemented for any callback function type that matches the
144+
/// signature.
145+
impl<F: Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult + Send + Sync> Postprocessor
146+
for F
147+
{
148+
fn postprocess(&self, ctx: &mut Context, events: &mut MarkdownEvents) -> PostprocessorResult {
149+
self(ctx, events)
150+
}
151+
}
152+
153+
/// EmbedPostprocessor is like [Postprocessor] but for note embeds, and it is passed to
154+
/// [Exporter::add_embed_postprocessor_impl].
155+
pub trait EmbedPostprocessor: Send + Sync {
149156
fn embed_postprocess(
150157
&self,
151158
ctx: &mut Context,
152159
events: &mut MarkdownEvents,
153160
) -> PostprocessorResult;
154161
}
155162

163+
impl<F: Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult + Send + Sync>
164+
EmbedPostprocessor for F
165+
{
166+
fn embed_postprocess(
167+
&self,
168+
ctx: &mut Context,
169+
events: &mut MarkdownEvents,
170+
) -> PostprocessorResult {
171+
self(ctx, events)
172+
}
173+
}
174+
156175
const PERCENTENCODE_CHARS: &AsciiSet = &CONTROLS.add(b' ').add(b'(').add(b')').add(b'%').add(b'?');
157176
const NOTE_RECURSION_LIMIT: usize = 10;
158177

@@ -232,23 +251,6 @@ pub enum PostprocessorResult {
232251
StopAndSkipNote,
233252
}
234253

235-
#[derive(Clone)]
236-
enum PostprocessorRef<'p> {
237-
Function(&'p Postprocessor<'p>),
238-
Trait(&'p dyn Postprocess),
239-
EmbedTrait(&'p dyn EmbedPostprocess),
240-
}
241-
242-
impl<'p> PostprocessorRef<'p> {
243-
fn call(&'p self, ctx: &mut Context, events: &mut MarkdownEvents) -> PostprocessorResult {
244-
match self {
245-
PostprocessorRef::Function(f) => f(ctx, events),
246-
PostprocessorRef::Trait(t) => t.postprocess(ctx, events),
247-
PostprocessorRef::EmbedTrait(t) => t.embed_postprocess(ctx, events),
248-
}
249-
}
250-
}
251-
252254
#[derive(Clone)]
253255
/// Exporter provides the main interface to this library.
254256
///
@@ -264,8 +266,8 @@ pub struct Exporter<'a> {
264266
vault_contents: Option<Vec<PathBuf>>,
265267
walk_options: WalkOptions<'a>,
266268
process_embeds_recursively: bool,
267-
postprocessors: Vec<PostprocessorRef<'a>>,
268-
embed_postprocessors: Vec<PostprocessorRef<'a>>,
269+
postprocessors: Vec<&'a dyn Postprocessor>,
270+
embed_postprocessors: Vec<&'a dyn EmbedPostprocessor>,
269271
}
270272

271273
impl<'a> fmt::Debug for Exporter<'a> {
@@ -347,34 +349,38 @@ impl<'a> Exporter<'a> {
347349
}
348350

349351
/// Append a function to the chain of [postprocessors][Postprocessor] to run on exported Obsidian Markdown notes.
350-
pub fn add_postprocessor(&mut self, processor: &'a Postprocessor) -> &mut Exporter<'a> {
351-
self.postprocessors
352-
.push(PostprocessorRef::Function(processor));
352+
pub fn add_postprocessor(
353+
&mut self,
354+
processor: &'a (impl Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult + Send + Sync),
355+
) -> &mut Exporter<'a> {
356+
self.postprocessors.push(processor);
353357
self
354358
}
355359

356-
/// Append a trait implementation of [Postprocess] to the chain of [postprocessors] to run on
357-
/// Obsidian Markdown notes.
358-
pub fn add_postprocessor_impl(&mut self, processor: &'a dyn Postprocess) -> &mut Exporter<'a> {
359-
self.postprocessors.push(PostprocessorRef::Trait(processor));
360+
/// Append a trait object to the chain of [postprocessors] to run on Obsidian Markdown notes.
361+
pub fn add_postprocessor_impl(
362+
&mut self,
363+
processor: &'a dyn Postprocessor,
364+
) -> &mut Exporter<'a> {
365+
self.postprocessors.push(processor);
360366
self
361367
}
362368

363-
/// Append a function to the chain of [postprocessors][Postprocessor] for embeds.
364-
pub fn add_embed_postprocessor(&mut self, processor: &'a Postprocessor) -> &mut Exporter<'a> {
365-
self.embed_postprocessors
366-
.push(PostprocessorRef::Function(processor));
369+
/// Append a function to the chain of [postprocessors][EmbedPostprocessor] for embeds.
370+
pub fn add_embed_postprocessor(
371+
&mut self,
372+
processor: &'a (impl Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult + Send + Sync),
373+
) -> &mut Exporter<'a> {
374+
self.embed_postprocessors.push(processor);
367375
self
368376
}
369377

370-
/// Append a trait implementation of [EmbedPostprocess] to the chain of [postprocessors] for
371-
/// embeds.
378+
/// Append a trait object to the chain of [postprocessors] for embeds.
372379
pub fn add_embed_postprocessor_impl(
373380
&mut self,
374-
processor: &'a dyn EmbedPostprocess,
381+
processor: &'a dyn EmbedPostprocessor,
375382
) -> &mut Exporter<'a> {
376-
self.embed_postprocessors
377-
.push(PostprocessorRef::EmbedTrait(processor));
383+
self.embed_postprocessors.push(processor);
378384
self
379385
}
380386

@@ -454,7 +460,7 @@ impl<'a> Exporter<'a> {
454460
let (frontmatter, mut markdown_events) = self.parse_obsidian_note(src, &context)?;
455461
context.frontmatter = frontmatter;
456462
for processor in &self.postprocessors {
457-
match processor.call(&mut context, &mut markdown_events) {
463+
match processor.postprocess(&mut context, &mut markdown_events) {
458464
PostprocessorResult::StopHere => break,
459465
PostprocessorResult::StopAndSkipNote => return Ok(()),
460466
PostprocessorResult::Continue => (),
@@ -659,7 +665,7 @@ impl<'a> Exporter<'a> {
659665
for processor in &self.embed_postprocessors {
660666
// Postprocessors running on embeds shouldn't be able to change frontmatter (or
661667
// any other metadata), so we give them a clone of the context.
662-
match processor.call(&mut child_context, &mut events) {
668+
match processor.embed_postprocess(&mut child_context, &mut events) {
663669
PostprocessorResult::StopHere => break,
664670
PostprocessorResult::StopAndSkipNote => {
665671
events = vec![];

tests/postprocessors_test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use obsidian_export::postprocessors::softbreaks_to_hardbreaks;
22
use obsidian_export::{
3-
Context, EmbedPostprocess, Exporter, MarkdownEvents, Postprocess, PostprocessorResult,
3+
Context, EmbedPostprocessor, Exporter, MarkdownEvents, Postprocessor, PostprocessorResult,
44
};
55
use pretty_assertions::assert_eq;
66
use pulldown_cmark::{CowStr, Event};
@@ -148,7 +148,7 @@ fn test_postprocessor_impl() {
148148
parents: Mutex<HashSet<PathBuf>>,
149149
embeds: Mutex<u32>,
150150
}
151-
impl Postprocess for Impl {
151+
impl Postprocessor for Impl {
152152
fn postprocess(
153153
&self,
154154
ctx: &mut Context,
@@ -161,7 +161,7 @@ fn test_postprocessor_impl() {
161161
PostprocessorResult::Continue
162162
}
163163
}
164-
impl EmbedPostprocess for Impl {
164+
impl EmbedPostprocessor for Impl {
165165
fn embed_postprocess(
166166
&self,
167167
_ctx: &mut Context,

0 commit comments

Comments
 (0)