marco_core/parser/
shared.rs1use crate::parser::position::{Position, Span as ParserSpan};
5use nom_locate::LocatedSpan;
6
7pub type GrammarSpan<'a> = LocatedSpan<&'a str>;
9
10pub fn to_parser_span(span: GrammarSpan) -> ParserSpan {
16 let start_line = span.location_line() as usize; let newline_count = span.fragment().matches('\n').count();
18 let end_line = start_line + newline_count;
19
20 let end_column = if span.fragment().ends_with('\n') {
21 1
23 } else if let Some(last_newline_pos) = span.fragment().rfind('\n') {
24 span.fragment()[last_newline_pos + 1..].len() + 1
26 } else {
27 span.get_column() + span.fragment().len()
29 };
30
31 let start = Position::new(start_line, span.get_column(), span.location_offset());
32 let end = Position::new(
33 end_line,
34 end_column,
35 span.location_offset() + span.fragment().len(),
36 );
37 ParserSpan::new(start, end)
38}
39
40pub fn to_parser_span_range(start: GrammarSpan, end: GrammarSpan) -> ParserSpan {
46 let start_pos = Position::new(
47 start.location_line() as usize,
48 start.get_column(),
49 start.location_offset(),
50 );
51 let end_pos = Position::new(
52 end.location_line() as usize,
53 end.get_column(),
54 end.location_offset(),
55 );
56 ParserSpan::new(start_pos, end_pos)
57}
58
59pub fn to_parser_span_range_inclusive(start: GrammarSpan, end: GrammarSpan) -> ParserSpan {
64 let start_pos = Position::new(
65 start.location_line() as usize,
66 start.get_column(),
67 start.location_offset(),
68 );
69 let end_pos = Position::new(
70 end.location_line() as usize,
71 end.get_column() + end.fragment().len(),
72 end.location_offset() + end.fragment().len(),
73 );
74 ParserSpan::new(start_pos, end_pos)
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_to_parser_span_ascii() {
83 let input = GrammarSpan::new("hello");
84 let span = to_parser_span(input);
85 assert_eq!(span.start.line, 1);
86 assert_eq!(span.start.column, 1);
87 assert_eq!(span.end.column, 6); }
89
90 #[test]
91 fn test_to_parser_span_utf8_and_emoji() {
92 let input = GrammarSpan::new("Tëst");
93 let span = to_parser_span(input);
94 assert_eq!(span.start.column, 1);
95 assert_eq!(span.end.column, 6);
97
98 let input2 = GrammarSpan::new("🎨");
99 let span2 = to_parser_span(input2);
100 assert_eq!(span2.start.column, 1);
101 assert_eq!(span2.end.column, 5);
103 }
104}