@@ -7,7 +7,7 @@ use crate::common::TypeKey;
77use crate :: parser:: extset:: NodeExtSet ;
88use crate :: parser:: inline:: Text ;
99use crate :: parser:: renderer:: HTMLRenderer ;
10- use crate :: Renderer ;
10+ use crate :: { Renderer , Result } ;
1111
1212/// Single node in the CommonMark AST.
1313#[ derive( Debug ) ]
@@ -106,76 +106,91 @@ impl Node {
106106
107107 /// Execute function `f` recursively on every member of AST tree
108108 /// (using preorder deep-first search).
109- pub fn walk < ' a > ( & ' a self , mut f : impl FnMut ( & ' a Node , u32 ) ) {
109+ ///
110+ /// This function will stop early if closure returns any error.
111+ pub fn walk < ' a > ( & ' a self , mut f : impl FnMut ( & ' a Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
110112 // performance note: this is faster than emulating recursion using vec stack
111- fn walk_recursive < ' b > ( node : & ' b Node , depth : u32 , f : & mut impl FnMut ( & ' b Node , u32 ) ) {
112- f ( node, depth) ;
113+ fn walk_recursive < ' a > ( node : & ' a Node , depth : u32 , f : & mut impl FnMut ( & ' a Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
114+ f ( node, depth) ? ;
113115 for n in node. children . iter ( ) {
114- stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || {
115- walk_recursive ( n, depth + 1 , f) ;
116- } ) ;
116+ stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || -> Result < ( ) > {
117+ walk_recursive ( n, depth + 1 , f)
118+ } ) ? ;
117119 }
120+ Ok ( ( ) )
118121 }
119122
120- walk_recursive ( self , 0 , & mut f) ;
123+ walk_recursive ( self , 0 , & mut f)
121124 }
122125
123126 /// Execute function `f` recursively on every member of AST tree
124127 /// (using preorder deep-first search).
125- pub fn walk_mut ( & mut self , mut f : impl FnMut ( & mut Node , u32 ) ) {
126- // performance note: this is faster than emulating recursion using vec stack
127- fn walk_recursive ( node : & mut Node , depth : u32 , f : & mut impl FnMut ( & mut Node , u32 ) ) {
128- f ( node, depth) ;
128+ ///
129+ /// This function will stop early if closure returns any error.
130+ pub fn walk_mut ( & mut self , mut f : impl FnMut ( & mut Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
131+ // note: lifetime constrains are different from non-mut walk due to mutability
132+ fn walk_recursive ( node : & mut Node , depth : u32 , f : & mut impl FnMut ( & mut Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
133+ f ( node, depth) ?;
129134 for n in node. children . iter_mut ( ) {
130- stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || {
131- walk_recursive ( n, depth + 1 , f) ;
132- } ) ;
135+ stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || -> Result < ( ) > {
136+ walk_recursive ( n, depth + 1 , f)
137+ } ) ? ;
133138 }
139+ Ok ( ( ) )
134140 }
135141
136- walk_recursive ( self , 0 , & mut f) ;
142+ walk_recursive ( self , 0 , & mut f)
137143 }
138144
139145 /// Execute function `f` recursively on every member of AST tree
140146 /// (using postorder deep-first search).
141- pub fn walk_post ( & self , mut f : impl FnMut ( & Node , u32 ) ) {
142- fn walk_recursive ( node : & Node , depth : u32 , f : & mut impl FnMut ( & Node , u32 ) ) {
147+ ///
148+ /// This function will stop early if closure returns any error.
149+ pub fn walk_post < ' a > ( & ' a self , mut f : impl FnMut ( & ' a Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
150+ // performance note: this is faster than emulating recursion using vec stack
151+ fn walk_recursive < ' a > ( node : & ' a Node , depth : u32 , f : & mut impl FnMut ( & ' a Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
143152 for n in node. children . iter ( ) {
144- stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || {
145- walk_recursive ( n, depth + 1 , f) ;
146- } ) ;
153+ stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || -> Result < ( ) > {
154+ walk_recursive ( n, depth + 1 , f)
155+ } ) ? ;
147156 }
148- f ( node, depth) ;
157+ f ( node, depth) ?;
158+ Ok ( ( ) )
149159 }
150160
151- walk_recursive ( self , 0 , & mut f) ;
161+ walk_recursive ( self , 0 , & mut f)
152162 }
153163
154164 /// Execute function `f` recursively on every member of AST tree
155165 /// (using postorder deep-first search).
156- pub fn walk_post_mut ( & mut self , mut f : impl FnMut ( & mut Node , u32 ) ) {
157- fn walk_recursive ( node : & mut Node , depth : u32 , f : & mut impl FnMut ( & mut Node , u32 ) ) {
166+ ///
167+ /// This function will stop early if closure returns any error.
168+ pub fn walk_post_mut ( & mut self , mut f : impl FnMut ( & mut Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
169+ // note: lifetime constrains are different from non-mut walk due to mutability
170+ fn walk_recursive ( node : & mut Node , depth : u32 , f : & mut impl FnMut ( & mut Node , u32 ) -> Result < ( ) > ) -> Result < ( ) > {
158171 for n in node. children . iter_mut ( ) {
159- stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || {
160- walk_recursive ( n, depth + 1 , f) ;
161- } ) ;
172+ stacker:: maybe_grow ( 64 * 1024 , 1024 * 1024 , || -> Result < ( ) > {
173+ walk_recursive ( n, depth + 1 , f)
174+ } ) ? ;
162175 }
163- f ( node, depth) ;
176+ f ( node, depth) ?;
177+ Ok ( ( ) )
164178 }
165179
166- walk_recursive ( self , 0 , & mut f) ;
180+ walk_recursive ( self , 0 , & mut f)
167181 }
168182
169183 /// Walk recursively through child nodes and collect all text nodes
170184 /// into a single string.
171185 pub fn collect_text ( & self ) -> String {
172186 let mut result = String :: new ( ) ;
173187
174- self . walk ( |node, _| {
188+ self . walk ( |node : & Node , _| {
175189 if let Some ( text) = node. cast :: < Text > ( ) {
176190 result. push_str ( text. content . as_str ( ) ) ;
177191 }
178- } ) ;
192+ Ok ( ( ) )
193+ } ) . unwrap ( ) ;
179194
180195 result
181196 }
@@ -185,7 +200,8 @@ impl Drop for Node {
185200 fn drop ( & mut self ) {
186201 self . walk_post_mut ( |node, _| {
187202 drop ( std:: mem:: take ( & mut node. children ) ) ;
188- } ) ;
203+ Ok ( ( ) )
204+ } ) . unwrap ( ) ;
189205 }
190206}
191207
0 commit comments