use crate::parser::position::{Position, Span as ParserSpan};
use nom_locate::LocatedSpan;
pub type GrammarSpan<'a> = LocatedSpan<&'a str>;
pub fn to_parser_span(span: GrammarSpan) -> ParserSpan {
let start_line = span.location_line() as usize; let newline_count = span.fragment().matches('\n').count();
let end_line = start_line + newline_count;
let end_column = if span.fragment().ends_with('\n') {
1
} else if let Some(last_newline_pos) = span.fragment().rfind('\n') {
span.fragment()[last_newline_pos + 1..].len() + 1
} else {
span.get_column() + span.fragment().len()
};
let start = Position::new(start_line, span.get_column(), span.location_offset());
let end = Position::new(
end_line,
end_column,
span.location_offset() + span.fragment().len(),
);
ParserSpan::new(start, end)
}
pub fn to_parser_span_range(start: GrammarSpan, end: GrammarSpan) -> ParserSpan {
let start_pos = Position::new(
start.location_line() as usize,
start.get_column(),
start.location_offset(),
);
let end_pos = Position::new(
end.location_line() as usize,
end.get_column(),
end.location_offset(),
);
ParserSpan::new(start_pos, end_pos)
}
pub fn to_parser_span_range_inclusive(start: GrammarSpan, end: GrammarSpan) -> ParserSpan {
let start_pos = Position::new(
start.location_line() as usize,
start.get_column(),
start.location_offset(),
);
let end_pos = Position::new(
end.location_line() as usize,
end.get_column() + end.fragment().len(),
end.location_offset() + end.fragment().len(),
);
ParserSpan::new(start_pos, end_pos)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_parser_span_ascii() {
let input = GrammarSpan::new("hello");
let span = to_parser_span(input);
assert_eq!(span.start.line, 1);
assert_eq!(span.start.column, 1);
assert_eq!(span.end.column, 6); }
#[test]
fn test_to_parser_span_utf8_and_emoji() {
let input = GrammarSpan::new("Tëst");
let span = to_parser_span(input);
assert_eq!(span.start.column, 1);
assert_eq!(span.end.column, 6);
let input2 = GrammarSpan::new("🎨");
let span2 = to_parser_span(input2);
assert_eq!(span2.start.column, 1);
assert_eq!(span2.end.column, 5);
}
}