@@ -26,7 +26,7 @@ use std::fmt::{self, Debug, Formatter};
2626use std:: mem;
2727use std:: panic:: RefUnwindSafe ;
2828use std:: str;
29- use std:: sync:: { Arc , Mutex } ;
29+ use std:: sync:: Arc ;
3030use typed_arena:: Arena ;
3131
3232use crate :: adapters:: HeadingAdapter ;
@@ -80,16 +80,16 @@ pub fn parse_document<'a>(
8080/// [`ParseOptions::broken_link_callback`].
8181#[ deprecated(
8282 since = "0.25.0" ,
83- note = "The broken link callback has been moved into ParseOptions<'c> ."
83+ note = "The broken link callback has been moved into ParseOptions."
8484) ]
85- pub fn parse_document_with_broken_link_callback < ' a , ' c > (
85+ pub fn parse_document_with_broken_link_callback < ' a > (
8686 arena : & ' a Arena < AstNode < ' a > > ,
8787 buffer : & str ,
88- options : & Options < ' c > ,
89- callback : Option < BrokenLinkCallback < ' c > > ,
88+ options : & Options ,
89+ callback : Arc < dyn BrokenLinkCallback > ,
9090) -> & ' a AstNode < ' a > {
9191 let mut options_with_callback = options. clone ( ) ;
92- options_with_callback. parse . broken_link_callback = callback . map ( |cb| Arc :: new ( Mutex :: new ( cb ) ) ) ;
92+ options_with_callback. parse . broken_link_callback = Some ( callback ) ;
9393 parse_document ( arena, buffer, & options_with_callback)
9494}
9595
@@ -100,8 +100,26 @@ pub fn parse_document_with_broken_link_callback<'a, 'c>(
100100/// [`BrokenLinkReference`] argument. If a [`ResolvedReference`] is returned, it
101101/// is used as the link; otherwise, no link is made and the reference text is
102102/// preserved in its entirety.
103- pub type BrokenLinkCallback < ' c > =
104- & ' c mut dyn FnMut ( BrokenLinkReference ) -> Option < ResolvedReference > ;
103+ pub trait BrokenLinkCallback : RefUnwindSafe + Send + Sync {
104+ /// Potentially resolve a single broken link reference.
105+ fn resolve ( & self , broken_link_reference : BrokenLinkReference ) -> Option < ResolvedReference > ;
106+ }
107+
108+ impl Debug for dyn BrokenLinkCallback {
109+ fn fmt ( & self , formatter : & mut Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
110+ formatter. write_str ( "<dyn BrokenLinkCallback>" )
111+ }
112+ }
113+
114+ impl < F > BrokenLinkCallback for F
115+ where
116+ F : Fn ( BrokenLinkReference ) -> Option < ResolvedReference > ,
117+ F : RefUnwindSafe + Send + Sync ,
118+ {
119+ fn resolve ( & self , broken_link_reference : BrokenLinkReference ) -> Option < ResolvedReference > {
120+ self ( broken_link_reference)
121+ }
122+ }
105123
106124/// Struct to the broken link callback, containing details on the link reference
107125/// which failed to find a match.
@@ -116,7 +134,7 @@ pub struct BrokenLinkReference<'l> {
116134 pub original : & ' l str ,
117135}
118136
119- pub struct Parser < ' a , ' o , ' c > {
137+ pub struct Parser < ' a , ' o > {
120138 arena : & ' a Arena < AstNode < ' a > > ,
121139 refmap : RefMap ,
122140 root : & ' a AstNode < ' a > ,
@@ -135,19 +153,18 @@ pub struct Parser<'a, 'o, 'c> {
135153 last_line_length : usize ,
136154 last_buffer_ended_with_cr : bool ,
137155 total_size : usize ,
138- options : & ' o Options < ' c > ,
156+ options : & ' o Options ,
139157}
140158
141159#[ derive( Default , Debug , Clone ) ]
142160#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
143- /// Umbrella options struct. `'c` represents the lifetime of any callback
144- /// closure options may take.
145- pub struct Options < ' c > {
161+ /// Umbrella options struct.
162+ pub struct Options {
146163 /// Enable CommonMark extensions.
147164 pub extension : ExtensionOptions ,
148165
149166 /// Configure parse-time options.
150- pub parse : ParseOptions < ' c > ,
167+ pub parse : ParseOptions ,
151168
152169 /// Configure render-time options.
153170 pub render : RenderOptions ,
@@ -581,10 +598,10 @@ pub struct ExtensionOptions {
581598}
582599
583600#[ non_exhaustive]
584- #[ derive( Default , Clone , Builder ) ]
601+ #[ derive( Default , Clone , Debug , Builder ) ]
585602#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
586603/// Options for parser functions.
587- pub struct ParseOptions < ' c > {
604+ pub struct ParseOptions {
588605 /// Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation.
589606 ///
590607 /// ```
@@ -643,18 +660,18 @@ pub struct ParseOptions<'c> {
643660 /// used as the link destination and title if not [`None`].
644661 ///
645662 /// ```
646- /// # use std::{str, sync::{ Arc, Mutex} };
663+ /// # use std::{str, sync::Arc};
647664 /// # use comrak::{markdown_to_html, BrokenLinkReference, Options, ResolvedReference};
648- /// let mut cb = |link_ref: BrokenLinkReference| match link_ref.normalized {
665+ /// let cb = |link_ref: BrokenLinkReference| match link_ref.normalized {
649666 /// "foo" => Some(ResolvedReference {
650667 /// url: "https://www.rust-lang.org/".to_string(),
651668 /// title: "The Rust Language".to_string(),
652669 /// }),
653670 /// _ => None,
654671 /// };
655- ///
672+ ///
656673 /// let mut options = Options::default();
657- /// options.parse.broken_link_callback = Some(Arc::new(Mutex::new(&mut cb) ));
674+ /// options.parse.broken_link_callback = Some(Arc::new(cb ));
658675 ///
659676 /// let output = markdown_to_html(
660677 /// "# Cool input!\nWow look at this cool [link][foo]. A [broken link] renders as text.",
@@ -666,22 +683,7 @@ pub struct ParseOptions<'c> {
666683 /// <a href=\"https://www.rust-lang.org/\" title=\"The Rust Language\">link</a>. \
667684 /// A [broken link] renders as text.</p>\n");
668685 #[ cfg_attr( feature = "arbitrary" , arbitrary( default ) ) ]
669- pub broken_link_callback : Option < Arc < Mutex < BrokenLinkCallback < ' c > > > > ,
670- }
671-
672- impl < ' c > fmt:: Debug for ParseOptions < ' c > {
673- fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
674- let mut struct_fmt = f. debug_struct ( "ParseOptions" ) ;
675- struct_fmt. field ( "smart" , & self . smart ) ;
676- struct_fmt. field ( "default_info_string" , & self . default_info_string ) ;
677- struct_fmt. field ( "relaxed_tasklist_matching" , & self . relaxed_tasklist_matching ) ;
678- struct_fmt. field ( "relaxed_autolinks" , & self . relaxed_autolinks ) ;
679- struct_fmt. field (
680- "broken_link_callback.is_some()" ,
681- & self . broken_link_callback . is_some ( ) ,
682- ) ;
683- struct_fmt. finish ( )
684- }
686+ pub broken_link_callback : Option < Arc < dyn BrokenLinkCallback > > ,
685687}
686688
687689#[ non_exhaustive]
@@ -1088,8 +1090,8 @@ struct FootnoteDefinition<'a> {
10881090 total_references : u32 ,
10891091}
10901092
1091- impl < ' a , ' o , ' c : ' o > Parser < ' a , ' o , ' c > {
1092- fn new ( arena : & ' a Arena < AstNode < ' a > > , root : & ' a AstNode < ' a > , options : & ' o Options < ' c > ) -> Self {
1093+ impl < ' a , ' o > Parser < ' a , ' o > {
1094+ fn new ( arena : & ' a Arena < AstNode < ' a > > , root : & ' a AstNode < ' a > , options : & ' o Options ) -> Self {
10931095 Parser {
10941096 arena,
10951097 refmap : RefMap :: new ( ) ,
0 commit comments