@@ -487,12 +487,12 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
487487 if let Some ( text) = line. strip_prefix ( '#' ) {
488488 comments. push ( text. to_string ( ) ) ;
489489 if lines. peek ( ) . is_none ( ) {
490+ // Special handling for the case where the last line is a comment.
490491 records. push ( Record :: Comment ( comments) ) ;
491- comments = vec ! [ ] ;
492+ break ;
492493 }
493494 continue ;
494495 }
495-
496496 if !comments. is_empty ( ) {
497497 records. push ( Record :: Comment ( comments) ) ;
498498 comments = vec ! [ ] ;
@@ -567,17 +567,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
567567 }
568568 _ => return Err ( ParseErrorKind :: InvalidLine ( line. into ( ) ) . at ( loc) ) ,
569569 } ;
570- let mut sql = match lines. next ( ) {
571- Some ( ( _, line) ) => line. into ( ) ,
572- None => return Err ( ParseErrorKind :: UnexpectedEOF . at ( loc. next_line ( ) ) ) ,
573- } ;
574- for ( _, line) in & mut lines {
575- if line. is_empty ( ) {
576- break ;
577- }
578- sql += "\n " ;
579- sql += line;
580- }
570+ let ( sql, _) = parse_lines ( & mut lines, & loc, None ) ?;
581571 records. push ( Record :: Statement {
582572 loc,
583573 conditions : std:: mem:: take ( & mut conditions) ,
@@ -619,22 +609,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
619609
620610 // The SQL for the query is found on second an subsequent lines of the record
621611 // up to first line of the form "----" or until the end of the record.
622- let mut sql = match lines. next ( ) {
623- Some ( ( _, line) ) => line. into ( ) ,
624- None => return Err ( ParseErrorKind :: UnexpectedEOF . at ( loc. next_line ( ) ) ) ,
625- } ;
626- let mut has_result = false ;
627- for ( _, line) in & mut lines {
628- if line. is_empty ( ) {
629- break ;
630- }
631- if line == "----" {
632- has_result = true ;
633- break ;
634- }
635- sql += "\n " ;
636- sql += line;
637- }
612+ let ( sql, has_result) = parse_lines ( & mut lines, & loc, Some ( "----" ) ) ?;
638613 // Lines following the "----" are expected results of the query, one value per line.
639614 let mut expected_results = vec ! [ ] ;
640615 if has_result {
@@ -659,17 +634,7 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
659634 }
660635 [ "system" , "ok" ] => {
661636 // TODO: we don't support asserting error message for system command
662- let mut command = match lines. next ( ) {
663- Some ( ( _, line) ) => line. into ( ) ,
664- None => return Err ( ParseErrorKind :: UnexpectedEOF . at ( loc. next_line ( ) ) ) ,
665- } ;
666- for ( _, line) in & mut lines {
667- if line. is_empty ( ) {
668- break ;
669- }
670- command += "\n " ;
671- command += line;
672- }
637+ let ( command, _) = parse_lines ( & mut lines, & loc, None ) ?;
673638 records. push ( Record :: System {
674639 loc,
675640 conditions : std:: mem:: take ( & mut conditions) ,
@@ -742,6 +707,35 @@ fn parse_file_inner<T: ColumnType>(loc: Location) -> Result<Vec<Record<T>>, Pars
742707 Ok ( records)
743708}
744709
710+ /// Parse one or more lines until empty line or a delimiter.
711+ fn parse_lines < ' a > (
712+ lines : & mut impl Iterator < Item = ( usize , & ' a str ) > ,
713+ loc : & Location ,
714+ delimiter : Option < & str > ,
715+ ) -> Result < ( String , bool ) , ParseError > {
716+ let mut found_delimiter = false ;
717+ let mut out = match lines. next ( ) {
718+ Some ( ( _, line) ) => Ok ( line. into ( ) ) ,
719+ None => Err ( ParseErrorKind :: UnexpectedEOF . at ( loc. clone ( ) . next_line ( ) ) ) ,
720+ } ?;
721+
722+ for ( _, line) in lines {
723+ if line. is_empty ( ) {
724+ break ;
725+ }
726+ if let Some ( delimiter) = delimiter {
727+ if line == delimiter {
728+ found_delimiter = true ;
729+ break ;
730+ }
731+ }
732+ out += "\n " ;
733+ out += line;
734+ }
735+
736+ Ok ( ( out, found_delimiter) )
737+ }
738+
745739#[ cfg( test) ]
746740mod tests {
747741 use std:: io:: Write ;
0 commit comments