fn expected_diagnostics(path: &Path) -> eyre::Result<ExpectedDiagnostics> {
    let file_contents = std::fs::read_to_string(path)?;

    let diagnostic_marker = regex::Regex::new(
        r"^(?P<prefix>[^#]*)#!\s*(?P<highlight>\^+)?\s*(?P<type>RUN)?\s*(?P<severity>ERROR|WARNING|INFO)\s*(?P<msg>.*)",
    )
    .unwrap();

    let output_marker = regex::Regex::new(r"^(?P<prefix>[^#]*)#!\s*OUTPUT\s+(?P<msg>.*)").unwrap();

    let any_output_marker = regex::Regex::new(r"^(?P<prefix>[^#]*)#!\s*OUTPUT ANY").unwrap();

    let any_marker = regex::Regex::new(r"^[^#]*#!").unwrap();

    let mut last_code_line = 1;
    let mut compile_diagnostics = vec![];
    let mut runtime_diagnostics = vec![];
    let mut output = vec![];
    let mut any_output_marker_seen = None;
    for (line, line_number) in file_contents.lines().zip(1..) {
        if let Some(c) = diagnostic_marker.captures(line) {
            let start_line = if c["prefix"].chars().all(char::is_whitespace) {
                // A comment alone on a line, like `#! ERROR ...`, will apply to the
                // last code line.
                last_code_line
            } else {
                // A comment at the end of a line, like `foo() #! ERROR`, applies to
                // that line.
                line_number
            };

            let highlight = c.name("highlight");
            let start_column = highlight.map(|m| m.start() as u32 + 1);
            let end_line_column = highlight.map(|m| (start_line, m.end() as u32 + 1));
            let severity = c["severity"].to_string();
            let message = Regex::new(&c["msg"])?;
            let expected = ExpectedDiagnostic {
                start_line,
                start_column,
                end_line_column,
                severity,
                message,
            };
            let type_ = c.name("type").map_or("COMPILE", |m| m.as_str());

            match type_ {
                "COMPILE" => {
                    compile_diagnostics.push(expected);
                }
                "RUN" => {
                    runtime_diagnostics.push(expected);
                }
                wrong => {
                    eyre::bail!("unexpected diagnostic type {} in {:?}", wrong, path);
                }
            }
        } else if any_output_marker.is_match(line) {
            any_output_marker_seen = Some(line_number);
        } else if let Some(c) = output_marker.captures(line) {
            let line1 = if c["prefix"].chars().all(char::is_whitespace) {
                // A comment alone on a line, like `#! ERROR ...`, will apply to the
                // last code line.
                last_code_line
            } else {
                // A comment at the end of a line, like `foo() #! ERROR`, applies to
                // that line.
                line_number
            };
            let message = Regex::new(&c["msg"])?;
            output.push(ExpectedOutput { line1, message });
        } else if any_marker.is_match(line) {
            eyre::bail!(
                "`#!` marker on line {} doesn't have expected form",
                line_number
            )
        } else {
            last_code_line = line_number;
        }
    }

    if let Some(any_line) = any_output_marker_seen {
        if let Some(o) = output.get(0) {
            eyre::bail!(
                "both 'OUTPUT ANY' (on line {}) and specific output (e.g. on line {}) found",
                any_line,
                o.line1
            );
        }
    }

    Ok(ExpectedDiagnostics {
        compile: compile_diagnostics,
        runtime: runtime_diagnostics,
        output: if any_output_marker_seen.is_some() {
            None
        } else {
            Some(output)
        },
    })
}
/// Returns the diagnostics that we expect to see in the file, sorted by line number.
Returns the diagnostics that we expect to see in the file, sorted by line number.
Returns the diagnostics that we expect to see in the file sorted by line number .
fn expected_diagnostics(path: &Path) -> eyre::Result<ExpectedDiagnostics> {
    let file_contents = std::fs::read_to_string(path)?;
    let diagnostic_marker = regex::Regex::new(
        r"^(?P<prefix>[^#]*)#!\s*(?P<highlight>\^+)?\s*(?P<type>RUN)?\s*(?P<severity>ERROR|WARNING|INFO)\s*(?P<msg>.*)",
    )
    .unwrap();
    let output_marker = regex::Regex::new(r"^(?P<prefix>[^#]*)#!\s*OUTPUT\s+(?P<msg>.*)").unwrap();
    let any_output_marker = regex::Regex::new(r"^(?P<prefix>[^#]*)#!\s*OUTPUT ANY").unwrap();
    let any_marker = regex::Regex::new(r"^[^#]*#!").unwrap();
    let mut last_code_line = 1;
    let mut compile_diagnostics = vec![];
    let mut runtime_diagnostics = vec![];
    let mut output = vec![];
    let mut any_output_marker_seen = None;
    for (line, line_number) in file_contents.lines().zip(1..) {
        if let Some(c) = diagnostic_marker.captures(line) {
            let start_line = if c["prefix"].chars().all(char::is_whitespace) {
                // A comment alone on a line, like `#! ERROR ...`, will apply to the
                // last code line.
                last_code_line
            } else {
                // A comment at the end of a line, like `foo() #! ERROR`, applies to
                // that line.
                line_number
            };
            let highlight = c.name("highlight");
            let start_column = highlight.map(|m| m.start() as u32 + 1);
            let end_line_column = highlight.map(|m| (start_line, m.end() as u32 + 1));
            let severity = c["severity"].to_string();
            let message = Regex::new(&c["msg"])?;
            let expected = ExpectedDiagnostic {
                start_line,
                start_column,
                end_line_column,
                severity,
                message,
            };
            let type_ = c.name("type").map_or("COMPILE", |m| m.as_str());
            match type_ {
                "COMPILE" => {
                    compile_diagnostics.push(expected);
                }
                "RUN" => {
                    runtime_diagnostics.push(expected);
                }
                wrong => {
                    eyre::bail!("unexpected diagnostic type {} in {:?}", wrong, path);
                }
            }
        } else if any_output_marker.is_match(line) {
            any_output_marker_seen = Some(line_number);
        } else if let Some(c) = output_marker.captures(line) {
            let line1 = if c["prefix"].chars().all(char::is_whitespace) {
                // A comment alone on a line, like `#! ERROR ...`, will apply to the
                // last code line.
                last_code_line
            } else {
                // A comment at the end of a line, like `foo() #! ERROR`, applies to
                // that line.
                line_number
            };
            let message = Regex::new(&c["msg"])?;
            output.push(ExpectedOutput { line1, message });
        } else if any_marker.is_match(line) {
            eyre::bail!(
                "`#!` marker on line {} doesn't have expected form",
                line_number
            )
        } else {
            last_code_line = line_number;
        }
    }
    if let Some(any_line) = any_output_marker_seen {
        if let Some(o) = output.get(0) {
            eyre::bail!(
                "both 'OUTPUT ANY' (on line {}) and specific output (e.g. on line {}) found",
                any_line,
                o.line1
            );
        }
    }
    Ok(ExpectedDiagnostics {
        compile: compile_diagnostics,
        runtime: runtime_diagnostics,
        output: if any_output_marker_seen.is_some() {
            None
        } else {
            Some(output)
        },
    })
}
fn expected_diagnostics ( path : & Path ) -> eyre :: Result < ExpectedDiagnostics > { let file_contents = std :: fs :: read_to_string ( path ) ? ; let diagnostic_marker = regex :: Regex :: new ( r"^(?P<prefix>[^#]*)#!\s*(?P<highlight>\^+)?\s*(?P<type>RUN)?\s*(?P<severity>ERROR|WARNING|INFO)\s*(?P<msg>.*)" , ) . unwrap ( ) ; let output_marker = regex :: Regex :: new ( r"^(?P<prefix>[^#]*)#!\s*OUTPUT\s+(?P<msg>.*)" ) . unwrap ( ) ; let any_output_marker = regex :: Regex :: new ( r"^(?P<prefix>[^#]*)#!\s*OUTPUT ANY" ) . unwrap ( ) ; let any_marker = regex :: Regex :: new ( r"^[^#]*#!" ) . unwrap ( ) ; let mut last_code_line = 1 ; let mut compile_diagnostics = vec ! [ ] ; let mut runtime_diagnostics = vec ! [ ] ; let mut output = vec ! [ ] ; let mut any_output_marker_seen = None ; for ( line , line_number ) in file_contents . lines ( ) . zip ( 1 .. ) { if let Some ( c ) = diagnostic_marker . captures ( line ) { let start_line = if c [ " " ] . chars ( ) . all ( char :: is_whitespace ) { // A comment alone on a line, like `#! ERROR ...`, will apply to the // last code line. last_code_line } else { // A comment at the end of a line, like `foo() #! ERROR`, applies to // that line. line_number } ; let highlight = c . name ( " " ) ; let start_column = highlight . map ( | m | m . start ( ) as u32 + 1 ) ; let end_line_column = highlight . map ( | m | ( start_line , m . end ( ) as u32 + 1 ) ) ; let severity = c [ " " ] . to_string ( ) ; let message = Regex :: new ( & c [ " " ] ) ? ; let expected = ExpectedDiagnostic { start_line , start_column , end_line_column , severity , message , } ; let type_ = c . name ( " " ) . map_or ( " " , | m | m . as_str ( ) ) ; match type_ { " " => { compile_diagnostics . push ( expected ) ; } " " => { runtime_diagnostics . push ( expected ) ; } wrong => { eyre :: bail ! ( " " wrong path ) ; } } } else if any_output_marker . is_match ( line ) { any_output_marker_seen = Some ( line_number ) ; } else if let Some ( c ) = output_marker . captures ( line ) { let line1 = if c [ " " ] . chars ( ) . all ( char :: is_whitespace ) { // A comment alone on a line, like `#! ERROR ...`, will apply to the // last code line. last_code_line } else { // A comment at the end of a line, like `foo() #! ERROR`, applies to // that line. line_number } ; let message = Regex :: new ( & c [ " " ] ) ? ; output . push ( ExpectedOutput { line1 , message } ) ; } else if any_marker . is_match ( line ) { eyre :: bail ! ( " " line_number ) } else { last_code_line = line_number ; } } if let Some ( any_line ) = any_output_marker_seen { if let Some ( o ) = output . get ( 0 ) { eyre :: bail ! ( " " any_line o line1 ) ; } } Ok ( ExpectedDiagnostics { compile : compile_diagnostics , runtime : runtime_diagnostics , output : if any_output_marker_seen . is_some ( ) { None } else { Some ( output ) } , } ) }
Returns the diagnostics that we expect to see in the file, sorted by line number.
Returns the diagnostics that we expect to see in the file sorted by line number .
path
&Path
path
&Path