diff options
author | Nadrieril | 2020-02-01 22:04:34 +0000 |
---|---|---|
committer | Nadrieril | 2020-02-01 22:04:34 +0000 |
commit | 70eede4fd012f49dfab0e2e27fb3a4e4bbff6325 (patch) | |
tree | f9b4a75b5ffc878f6d5e5a40bd7c13c8de94a9f9 /dhall/src/syntax | |
parent | 72a6fef65bb3d34be1f501a1f6de66fb8a54fa04 (diff) |
Implement once nice error using annotate_snippets
Diffstat (limited to 'dhall/src/syntax')
-rw-r--r-- | dhall/src/syntax/ast/span.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/dhall/src/syntax/ast/span.rs b/dhall/src/syntax/ast/span.rs index f9c7008..ffdd82c 100644 --- a/dhall/src/syntax/ast/span.rs +++ b/dhall/src/syntax/ast/span.rs @@ -24,6 +24,20 @@ pub enum Span { Artificial, } +impl ParsedSpan { + pub(crate) fn to_input(&self) -> String { + self.input.to_string() + } + /// Convert to a char range for consumption by annotate_snippets. + /// This compensates for https://github.com/rust-lang/annotate-snippets-rs/issues/24 + pub(crate) fn as_char_range(&self) -> (usize, usize) { + ( + char_idx_from_byte_idx(&self.input, self.start), + char_idx_from_byte_idx(&self.input, self.end), + ) + } +} + impl Span { pub(crate) fn make(input: Rc<str>, sp: pest::Span) -> Self { Span::Parsed(ParsedSpan { @@ -79,3 +93,19 @@ impl Span { format!("{}", err) } } + +/// Convert a byte idx into a string into a char idx for consumption by annotate_snippets. +fn char_idx_from_byte_idx(input: &str, idx: usize) -> usize { + let char_idx = input + .char_indices() + .enumerate() + .find(|(_, (i, _))| *i == idx) + .unwrap() + .0; + // Unix-style newlines are counted as two chars (see + // https://github.com/rust-lang/annotate-snippets-rs/issues/24). + let nbr_newlines = input[..idx].chars().filter(|c| *c == '\n').count(); + let nbr_carriage_returns = + input[..idx].chars().filter(|c| *c == '\r').count(); + char_idx + nbr_newlines - nbr_carriage_returns +} |