@@ -5,17 +5,14 @@ use nom::bytes::complete::{
55use nom:: character:: complete:: { alpha1, char, multispace0, multispace1} ;
66use nom:: combinator:: { map, map_res, opt, recognize, verify} ;
77use nom:: error:: Error ;
8- use nom:: multi:: { fold_many0 , many0, separated_list0} ;
8+ use nom:: multi:: { many0, separated_list0} ;
99use nom:: sequence:: { delimited, preceded, separated_pair, terminated, tuple} ;
1010use nom:: { AsChar , IResult } ;
1111
1212use crate :: parser_types:: * ;
1313
14- pub fn parse ( input : & str ) -> IResult < & str , Vec < Element < ' _ > > , Error < & str > > {
15- fold_many0 ( element, Vec :: new, |mut acc : Vec < Element > , item| {
16- item. push_to ( & mut acc) ;
17- acc
18- } ) ( input)
14+ pub fn parse ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
15+ map ( many0 ( element) , ParseResult :: from_results) ( input)
1916}
2017
2118/// Callback-based parser that invokes a callback for each element as it's parsed
@@ -25,15 +22,15 @@ pub fn parse_with_callback<'a, F>(
2522 mut callback : F ,
2623) -> IResult < & ' a str , ( ) , Error < & ' a str > >
2724where
28- F : FnMut ( Vec < Element < ' a > > ) -> Result < ( ) , String > ,
25+ F : FnMut ( ParseResult < ' a > ) -> Result < ( ) , String > ,
2926{
3027 let mut remaining = input;
3128
3229 while !remaining. is_empty ( ) {
3330 match element ( remaining) {
3431 Ok ( ( rest, result) ) => {
35- // Call the callback with parsed elements
36- if let Err ( _e) = callback ( result. into_vec ( ) ) {
32+ // Call the callback with parsed result
33+ if let Err ( _e) = callback ( result) {
3734 return Err ( nom:: Err :: Failure ( Error :: new (
3835 rest,
3936 nom:: error:: ErrorKind :: Fail ,
@@ -57,31 +54,20 @@ pub fn parse_expression(input: &str) -> IResult<&str, Expr<'_>, Error<&str>> {
5754 expr ( input)
5855}
5956
60- // Parses a string that may contain interpolated expressions like $(VAR)
61- pub fn parse_interpolated_string ( input : & str ) -> IResult < & str , Vec < Element < ' _ > > , Error < & str > > {
62- fold_many0 (
63- alt ( ( interpolated_expression, interpolated_text) ) ,
64- Vec :: new,
65- |mut acc : Vec < Element > , item| {
66- item. push_to ( & mut acc) ;
67- acc
68- } ,
57+ /// Parses a string that may contain interpolated expressions like $(VAR)
58+ pub fn parse_interpolated_string ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
59+ map (
60+ many0 ( alt ( ( interpolated_expression, interpolated_text) ) ) ,
61+ ParseResult :: from_results,
6962 ) ( input)
7063}
7164
7265fn element ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
7366 alt ( ( text, esi_tag, html) ) ( input)
7467}
7568
76- fn parse_interpolated ( input : & str ) -> IResult < & str , Vec < Element < ' _ > > , Error < & str > > {
77- fold_many0 (
78- interpolated_element,
79- Vec :: new,
80- |mut acc : Vec < Element > , item| {
81- item. push_to ( & mut acc) ;
82- acc
83- } ,
84- ) ( input)
69+ fn parse_interpolated ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
70+ map ( many0 ( interpolated_element) , ParseResult :: from_results) ( input)
8571}
8672
8773fn interpolated_element ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
@@ -113,9 +99,9 @@ fn parse_assign_attributes_short<'a>(attrs: Vec<(&'a str, &'a str)>) -> ParseRes
11399 let mut name = "" ;
114100 let mut value_str = "" ;
115101 for ( key, val) in attrs {
116- match key {
117- "name" => name = val,
118- "value" => value_str = val,
102+ match key. as_bytes ( ) {
103+ b "name" => name = val,
104+ b "value" => value_str = val,
119105 _ => { }
120106 }
121107 }
@@ -197,7 +183,7 @@ fn esi_assign_long(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
197183 parse_interpolated,
198184 tag ( "</esi:assign>" ) ,
199185 ) ) ,
200- |( attrs, content, _) | parse_assign_long ( attrs, content) ,
186+ |( attrs, content, _) | parse_assign_long ( attrs, content. into_vec ( ) ) ,
201187 ) ( input)
202188}
203189fn esi_except ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
@@ -207,7 +193,7 @@ fn esi_except(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
207193 parse_interpolated,
208194 tag ( "</esi:except>" ) ,
209195 ) ,
210- |v| ParseResult :: Single ( Element :: Esi ( Tag :: Except ( v) ) ) ,
196+ |v| ParseResult :: Single ( Element :: Esi ( Tag :: Except ( v. into_vec ( ) ) ) ) ,
211197 ) ( input)
212198}
213199fn esi_attempt ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
@@ -217,14 +203,14 @@ fn esi_attempt(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
217203 parse_interpolated,
218204 tag ( "</esi:attempt>" ) ,
219205 ) ,
220- |v| ParseResult :: Single ( Element :: Esi ( Tag :: Attempt ( v) ) ) ,
206+ |v| ParseResult :: Single ( Element :: Esi ( Tag :: Attempt ( v. into_vec ( ) ) ) ) ,
221207 ) ( input)
222208}
223209fn esi_try ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
224210 map ( delimited ( tag ( "<esi:try>" ) , parse, tag ( "</esi:try>" ) ) , |v| {
225211 let mut attempts = vec ! [ ] ;
226212 let mut except = None ;
227- for element in v {
213+ for element in v. into_vec ( ) {
228214 match element {
229215 Element :: Esi ( Tag :: Attempt ( cs) ) => attempts. push ( cs) ,
230216 Element :: Esi ( Tag :: Except ( cs) ) => {
@@ -250,7 +236,7 @@ fn esi_otherwise(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
250236 |( _, content, _) | {
251237 // Return the Otherwise tag followed by its content elements (same as esi_when)
252238 let mut result = vec ! [ Element :: Esi ( Tag :: Otherwise ) ] ;
253- result. extend ( content) ;
239+ result. extend ( content. into_vec ( ) ) ;
254240 ParseResult :: Multiple ( result)
255241 } ,
256242 ) ( input)
@@ -270,18 +256,18 @@ fn esi_when(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
270256 |( attrs, content, _) | {
271257 let test = attrs
272258 . iter ( )
273- . find ( |( key, _) | * key == "test" )
259+ . find ( |( key, _) | key. as_bytes ( ) == b "test")
274260 . map ( |( _, val) | * val)
275261 . unwrap_or ( "" ) ;
276262
277263 let match_name = attrs
278264 . iter ( )
279- . find ( |( key, _) | * key == "matchname" )
265+ . find ( |( key, _) | key. as_bytes ( ) == b "matchname")
280266 . map ( |( _, val) | val. to_string ( ) ) ;
281267
282268 // Return the When tag followed by its content elements as a marker
283269 let mut result = vec ! [ Element :: Esi ( Tag :: When { test, match_name } ) ] ;
284- result. extend ( content) ;
270+ result. extend ( content. into_vec ( ) ) ;
285271 ParseResult :: Multiple ( result)
286272 } ,
287273 ) ( input)
@@ -296,7 +282,7 @@ fn esi_choose(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
296282 let mut current_when: Option < WhenBranch > = None ;
297283 let mut in_otherwise = false ;
298284
299- for element in v {
285+ for element in v. into_vec ( ) {
300286 match element {
301287 Element :: Esi ( Tag :: When { test, match_name } ) => {
302288 // Save any previous when
@@ -366,15 +352,8 @@ fn parse_vars_attributes<'a>(
366352 attrs : Vec < ( & ' a str , & ' a str ) > ,
367353) -> Result < ParseResult < ' a > , & ' static str > {
368354 if let Some ( ( _k, v) ) = attrs. iter ( ) . find ( |( k, _v) | * k == "name" ) {
369- if let Ok ( ( _, expr) ) = expression ( v) {
370- // expression returns Vec<Element>, convert to ParseResult
371- if expr. is_empty ( ) {
372- Ok ( ParseResult :: Empty )
373- } else if expr. len ( ) == 1 {
374- Ok ( ParseResult :: Single ( expr. into_iter ( ) . next ( ) . unwrap ( ) ) )
375- } else {
376- Ok ( ParseResult :: Multiple ( expr) )
377- }
355+ if let Ok ( ( _, result) ) = expression ( v) {
356+ Ok ( result)
378357 } else {
379358 Err ( "failed to parse expression" )
380359 }
@@ -414,36 +393,21 @@ fn esi_tag_non_vars(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>>
414393
415394// Parser for content inside esi:vars - handles text, expressions, and most ESI tags (except nested vars)
416395// Supports nested variable expressions like $(VAR{$(other)}) as of the nom migration
417- fn parse_vars_content ( input : & str ) -> IResult < & str , Vec < Element < ' _ > > , Error < & str > > {
418- fold_many0 (
419- alt ( (
396+ fn parse_vars_content ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
397+ map (
398+ many0 ( alt ( (
420399 interpolated_text,
421400 interpolated_expression,
422401 esi_tag_non_vars,
423402 html,
424- ) ) ,
425- Vec :: new,
426- |mut acc : Vec < Element > , item| {
427- item. push_to ( & mut acc) ;
428- acc
429- } ,
403+ ) ) ) ,
404+ ParseResult :: from_results,
430405 ) ( input)
431406}
432407
433408fn esi_vars_long ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
434409 // Use parse_vars_content instead of parse_interpolated to avoid infinite recursion
435- map (
436- delimited ( tag ( "<esi:vars>" ) , parse_vars_content, tag ( "</esi:vars>" ) ) ,
437- |content| {
438- if content. is_empty ( ) {
439- ParseResult :: Empty
440- } else if content. len ( ) == 1 {
441- ParseResult :: Single ( content. into_iter ( ) . next ( ) . unwrap ( ) )
442- } else {
443- ParseResult :: Multiple ( content)
444- }
445- } ,
446- ) ( input)
410+ delimited ( tag ( "<esi:vars>" ) , parse_vars_content, tag ( "</esi:vars>" ) ) ( input)
447411}
448412
449413fn esi_comment ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
@@ -485,10 +449,10 @@ fn esi_include(input: &str) -> IResult<&str, ParseResult<'_>, Error<&str>> {
485449 let mut alt = None ;
486450 let mut continue_on_error = false ;
487451 for ( key, val) in attrs {
488- match key {
489- "src" => src = val,
490- "alt" => alt = Some ( val) ,
491- "onerror" => continue_on_error = val == "continue" ,
452+ match key. as_bytes ( ) {
453+ b "src" => src = val,
454+ b "alt" => alt = Some ( val) ,
455+ b "onerror" => continue_on_error = val. as_bytes ( ) == b "continue",
492456 _ => { }
493457 }
494458 }
@@ -779,8 +743,8 @@ fn expr(input: &str) -> IResult<&str, Expr<'_>, Error<&str>> {
779743 Ok ( ( rest, exp) )
780744 }
781745}
782- fn expression ( input : & str ) -> IResult < & str , Vec < Element < ' _ > > , Error < & str > > {
783- map ( expr, |x| vec ! [ Element :: Expr ( x) ] ) ( input)
746+ fn expression ( input : & str ) -> IResult < & str , ParseResult < ' _ > , Error < & str > > {
747+ map ( expr, |x| ParseResult :: Single ( Element :: Expr ( x) ) ) ( input)
784748}
785749
786750#[ cfg( test) ]
@@ -857,7 +821,7 @@ exception!
857821 fn test_new_parse_script_with_src ( ) {
858822 let ( rest, x) = parse ( "<sCripT src=\" whatever\" >" ) . unwrap ( ) ;
859823 assert_eq ! ( rest. len( ) , 0 ) ;
860- assert_eq ! ( x, [ Element :: Html ( "<sCripT src=\" whatever\" >" ) ] ) ;
824+ assert_eq ! ( x. into_vec ( ) , [ Element :: Html ( "<sCripT src=\" whatever\" >" ) ] ) ;
861825 }
862826 #[ test]
863827 fn test_new_parse_esi_vars_short ( ) {
@@ -874,7 +838,10 @@ exception!
874838 // The inner <esi:vars> tags should be treated as plain text/HTML
875839 let ( rest, x) = parse ( r#"<esi:vars>hello<br></esi:vars>"# ) . unwrap ( ) ;
876840 assert_eq ! ( rest. len( ) , 0 ) ;
877- assert_eq ! ( x, [ Element :: Text ( "hello" ) , Element :: Html ( "<br>" ) , ] ) ;
841+ assert_eq ! (
842+ x. into_vec( ) ,
843+ [ Element :: Text ( "hello" ) , Element :: Html ( "<br>" ) , ]
844+ ) ;
878845 }
879846
880847 #[ test]
@@ -894,9 +861,10 @@ exception!
894861 if rest. is_empty ( ) {
895862 // Inner vars should be treated as text/HTML
896863 eprintln ! ( "Parsed elements: {:?}" , elements) ;
864+ let elements_vec = elements. into_vec ( ) ;
897865 // We expect the text "outer<esi:vars>inner" to be captured somehow
898866 assert ! (
899- elements
867+ elements_vec
900868 . iter( )
901869 . any( |c| matches!( c, Element :: Text ( t) if t. contains( "inner" ) ) ) ,
902870 "Inner <esi:vars> content should be present as text"
@@ -922,7 +890,7 @@ exception!
922890 parse ( r#"<esi:vars name="$call('hello') matches $(var{'key'})"/>"# ) . unwrap ( ) ;
923891 assert_eq ! ( rest. len( ) , 0 ) ;
924892 assert_eq ! (
925- x,
893+ x. into_vec ( ) ,
926894 [ Element :: Expr ( Expr :: Comparison {
927895 left: Box :: new( Expr :: Call ( "call" , vec![ Expr :: String ( Some ( "hello" ) ) ] ) ) ,
928896 operator: Operator :: Matches ,
@@ -1012,14 +980,14 @@ exception!
1012980 fn test_new_parse_plain_text ( ) {
1013981 let ( rest, x) = parse ( "hello\n there" ) . unwrap ( ) ;
1014982 assert_eq ! ( rest. len( ) , 0 ) ;
1015- assert_eq ! ( x, [ Element :: Text ( "hello\n there" ) ] ) ;
983+ assert_eq ! ( x. into_vec ( ) , [ Element :: Text ( "hello\n there" ) ] ) ;
1016984 }
1017985 #[ test]
1018986 fn test_new_parse_interpolated ( ) {
1019987 let ( rest, x) = parse ( "hello $(foo)<esi:vars>goodbye $(foo)</esi:vars>" ) . unwrap ( ) ;
1020988 assert_eq ! ( rest. len( ) , 0 ) ;
1021989 assert_eq ! (
1022- x,
990+ x. into_vec ( ) ,
1023991 [
1024992 Element :: Text ( "hello $(foo)" ) ,
1025993 Element :: Text ( "goodbye " ) ,
@@ -1159,12 +1127,13 @@ exception!
11591127 #[ test]
11601128 fn test_html_comment_in_document ( ) {
11611129 let input = "<!-- comment --><div>test</div>" ;
1162- let ( rest, elements ) = parse ( input) . unwrap ( ) ;
1130+ let ( rest, result ) = parse ( input) . unwrap ( ) ;
11631131 assert_eq ! ( rest, "" ) ;
1132+ let elements = result. into_vec ( ) ;
11641133 // Comment should be parsed as one element
11651134 assert ! ( elements. len( ) >= 1 , "Expected at least 1 element" ) ;
11661135 match & elements[ 0 ] {
1167- Element :: Html ( s) => assert_eq ! ( s, & "<!-- comment -->" ) ,
1136+ Element :: Html ( s) => assert_eq ! ( * s, "<!-- comment -->" ) ,
11681137 _ => panic ! ( "Expected Html element for comment, got {:?}" , & elements[ 0 ] ) ,
11691138 }
11701139 }
0 commit comments