Skip to content

Commit

Permalink
Merge pull request #47 from ltratt/better_reporting_of_errors
Browse files Browse the repository at this point in the history
Better reporting of errors
  • Loading branch information
vext01 authored Jun 3, 2024
2 parents bf4cf6c + a1462a0 commit 88dc9f1
Showing 1 changed file with 95 additions and 13 deletions.
108 changes: 95 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,22 +271,39 @@ impl<'a> FMatcher<'a> {
match (ptnl, textl) {
(Some(x), Some(y)) => {
if x.trim() == LINE_ANCHOR_WILDCARD {
let text_lines_off_orig = text_lines_off;
ptnl = ptn_lines.next();
ptn_lines_off += 1;
match ptnl {
Some(x) => {
let mut succ = false;
while let Some(y) = textl {
text_lines_off += 1;
if self.match_line(&mut names, x, y) {
succ = true;
break;
}
text_lines_off += 1;
textl = text_lines.next();
}
text_lines_off -= 1;
if !succ {
return Err(FMatchError {
output_formatter: self.options.output_formatter,
ptn: self.ptn.to_owned(),
text: text.to_owned(),
ptn_line_off: ptn_lines_off,
text_line_off: text_lines_off_orig,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
});
}
}
None => return Ok(()),
}
} else if x.trim() == GROUP_ANCHOR_WILDCARD {
ptn_lines_off += 1;
// We now have to perform (bounded) backtracking
let ptn_lines_off_orig = ptn_lines_off;
let text_lines_off_orig = text_lines_off;
ptnl = ptn_lines.next();
Expand All @@ -295,11 +312,8 @@ impl<'a> FMatcher<'a> {
if ptnl.is_none() {
return Ok(());
}
// We now have to perform (bounded) backtracking
ptn_lines_off += 1;
let mut ptn_lines_sub = ptn_lines.clone();
let mut ptnl_sub = ptnl;
let mut ptn_lines_off_sub = ptn_lines_off;
let mut text_lines_sub = text_lines.clone();
let mut text_lines_off_sub = text_lines_off;
let mut textl_sub = textl;
Expand All @@ -314,7 +328,6 @@ impl<'a> FMatcher<'a> {
// We've matched everything successfully
ptn_lines = ptn_lines_sub;
ptnl = ptnl_sub;
ptn_lines_off = ptn_lines_off_sub;
text_lines = text_lines_sub;
textl = textl_sub;
text_lines_off = text_lines_off_sub;
Expand All @@ -330,6 +343,10 @@ impl<'a> FMatcher<'a> {
text: text.to_owned(),
ptn_line_off: ptn_lines_off_orig,
text_line_off: text_lines_off_orig,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
})
}
(None, _) => return Ok(()),
Expand All @@ -342,20 +359,24 @@ impl<'a> FMatcher<'a> {
text: text.to_owned(),
ptn_line_off: ptn_lines_off_orig,
text_line_off: text_lines_off_orig,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
});
}
(Some(x), Some(y)) => {
if self.match_line(&mut names_sub, x, y) {
ptnl_sub = ptn_lines_sub.next();
ptn_lines_off_sub += 1;
ptn_lines_off += 1;
textl_sub = text_lines_sub.next();
text_lines_off_sub += 1;
} else {
// We failed to match, so we need to reset the
// pattern, but advance the text.
ptn_lines_sub = ptn_lines.clone();
ptnl_sub = ptnl;
ptn_lines_off_sub += 1;
ptn_lines_off = ptn_lines_off_orig;
textl_sub = text_lines.next();
text_lines_off += 1;
text_lines_sub = text_lines.clone();
Expand All @@ -377,6 +398,10 @@ impl<'a> FMatcher<'a> {
text: text.to_owned(),
ptn_line_off: ptn_lines_off,
text_line_off: text_lines_off,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
});
}
}
Expand All @@ -401,6 +426,10 @@ impl<'a> FMatcher<'a> {
text: text.to_owned(),
ptn_line_off: ptn_lines_off + skipped,
text_line_off: text_lines_off,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
});
}
(None, _) => return Ok(()),
Expand All @@ -418,6 +447,10 @@ impl<'a> FMatcher<'a> {
text: text.to_owned(),
ptn_line_off: ptn_lines_off,
text_line_off: text_lines_off + skipped,
names: names
.iter()
.map(|(x, y)| (x.to_string(), y.to_string()))
.collect::<HashMap<_, _>>(),
});
}
}
Expand Down Expand Up @@ -567,6 +600,7 @@ pub struct FMatchError {
text: String,
ptn_line_off: usize,
text_line_off: usize,
names: HashMap<String, String>,
}

impl FMatchError {
Expand All @@ -588,6 +622,7 @@ impl fmt::Display for FMatchError {
self.ptn_line_off,
&self.text,
self.text_line_off,
&self.names,
),
OutputFormatter::InputThenSummary => {
fmt_raw(f, &self.text)?;
Expand All @@ -598,6 +633,7 @@ impl fmt::Display for FMatchError {
self.ptn_line_off,
&self.text,
self.text_line_off,
&self.names,
)
}
OutputFormatter::InputOnly => fmt_raw(f, &self.text),
Expand All @@ -622,6 +658,7 @@ fn fmt_summary(
ptn_line_off: usize,
text: &str,
text_line_off: usize,
names: &HashMap<String, String>,
) -> fmt::Result {
// Figure out how many characters are required for the LHS margin.
let err_mk_chars = ERROR_MARKER.chars().count() + ' '.len_utf8();
Expand Down Expand Up @@ -667,6 +704,16 @@ fn fmt_summary(

writeln!(f, "Pattern (error at line {}):", ptn_line_off)?;
display_lines(f, ptn, ptn_line_off)?;
if !names.is_empty() {
let mut names = names.iter().collect::<Vec<(_, _)>>();
names.sort();
let names = names
.iter()
.map(|(k, v)| format!("{k}: {v}"))
.collect::<Vec<_>>()
.join("\n ");
writeln!(f, "\nNames at point of failure:\n {names}")?;
}
writeln!(f, "\nText (error at line {}):", text_line_off)?;
display_lines(f, text, text_line_off)
}
Expand Down Expand Up @@ -990,7 +1037,7 @@ mod tests {
(err.ptn_line_off(), err.text_line_off())
};

assert_eq!(helper("a\n...\nd", "a\nb\nc"), (3, 3));
assert_eq!(helper("a\n...\nd", "a\nb\nc"), (3, 2));
assert_eq!(helper("a\nb...", "a\nb\nc"), (3, 3));
assert_eq!(helper("a\n...b...", "a\nxb\nc"), (3, 3));

Expand All @@ -1013,11 +1060,12 @@ mod tests {

assert_eq!(helper("...\nb\nc\nd\n", "a\nb\nc\n0\ne"), (4, 4));
assert_eq!(helper("...\nc\nd\n", "a\nb\nc\n0\ne"), (3, 4));
assert_eq!(helper("...\nd\n", "a\nb\nc\n0\ne"), (2, 5));
assert_eq!(helper("...\nd\n", "a\nb\nc\n0\ne"), (2, 1));

assert_eq!(helper("a\n..~\nc\nd\ne", "a\nb\nc\nd"), (2, 2));
assert_eq!(helper("a\n..~\nc\nd", "a\nb\nc\ne"), (2, 2));
assert_eq!(helper("a\n..~\nc\nd", "a\nc\ne\nc\ne"), (2, 2));
assert_eq!(helper("a\n..~\nc\nd\ne", "a\nb\nc\nd"), (3, 2));
assert_eq!(helper("a\n..~\nc\nd", "a\nb\nc\ne"), (3, 2));
assert_eq!(helper("a\n..~\nc\nd", "a\nc\ne\nc\ne"), (3, 2));
assert_eq!(helper("a\n..~\nc\nd\n...\nf", "a\ne\nf\nc\nd\ne"), (6, 6));
}

#[test]
Expand Down Expand Up @@ -1157,6 +1205,40 @@ Text (error at line 4):
|a
>>
Text (error at line 3):
|a
|
>> |b
"
);

assert_eq!(
helper(
OutputFormatter::SummaryOnly,
"a\n$1\n$1",
"a\nb\nc"
),
"Pattern (error at line 3):
|a
|$1
>> |$1
Names at point of failure:
$1: b
Text (error at line 3):
|a
|b
>> |c
"
);

assert_eq!(
helper(OutputFormatter::SummaryOnly, "a\n", "a\n\nb"),
"Pattern (error at line 2):
|a
>>
Text (error at line 3):
|a
|
Expand Down

0 comments on commit 88dc9f1

Please sign in to comment.