summaryrefslogtreecommitdiff
path: root/src/syntax/lines.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-10-01 11:32:48 +0200
committerLaurenz <laurmaedje@gmail.com>2020-10-01 11:32:48 +0200
commit885bfec5d7524845b41e180fadc9cf5626157eec (patch)
treef798e03d101d568a110a5c56f4a9bfa2be892928 /src/syntax/lines.rs
parent16f0bd430e0864a3bbd0139803e476be413cb3cb (diff)
Make syntax not depend on parse 📩
This would make it possible to split them into two separate crates.
Diffstat (limited to 'src/syntax/lines.rs')
-rw-r--r--src/syntax/lines.rs108
1 files changed, 0 insertions, 108 deletions
diff --git a/src/syntax/lines.rs b/src/syntax/lines.rs
deleted file mode 100644
index 6ea223c4..00000000
--- a/src/syntax/lines.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-//! Conversion of byte positions to line/column locations.
-
-use std::fmt::{self, Debug, Display, Formatter};
-
-use super::Pos;
-use crate::parse::{is_newline_char, Scanner};
-
-/// Enables conversion of byte position to locations.
-pub struct LineMap<'s> {
- src: &'s str,
- line_starts: Vec<Pos>,
-}
-
-impl<'s> LineMap<'s> {
- /// Create a new line map for a source string.
- pub fn new(src: &'s str) -> Self {
- let mut line_starts = vec![Pos::ZERO];
- let mut s = Scanner::new(src);
-
- while let Some(c) = s.eat_merging_crlf() {
- if is_newline_char(c) {
- line_starts.push(s.index().into());
- }
- }
-
- Self { src, line_starts }
- }
-
- /// Convert a byte position to a location.
- ///
- /// # Panics
- /// This panics if the position is out of bounds.
- pub fn location(&self, pos: Pos) -> Location {
- let line_index = match self.line_starts.binary_search(&pos) {
- Ok(i) => i,
- Err(i) => i - 1,
- };
-
- let line_start = self.line_starts[line_index];
- let head = &self.src[line_start.to_usize() .. pos.to_usize()];
- let column_index = head.chars().count();
-
- Location {
- line: 1 + line_index as u32,
- column: 1 + column_index as u32,
- }
- }
-}
-
-/// One-indexed line-column position in source code.
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
-pub struct Location {
- /// The one-indexed line.
- pub line: u32,
- /// The one-indexed column.
- pub column: u32,
-}
-
-impl Location {
- /// Create a new location from line and column.
- pub fn new(line: u32, column: u32) -> Self {
- Self { line, column }
- }
-}
-
-impl Debug for Location {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- Display::fmt(self, f)
- }
-}
-
-impl Display for Location {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "{}:{}", self.line, self.column)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- const TEST: &str = "äbcde\nf💛g\r\nhi\rjkl";
-
- #[test]
- fn test_line_map_new() {
- let map = LineMap::new(TEST);
- assert_eq!(map.line_starts, vec![Pos(0), Pos(7), Pos(15), Pos(18)]);
- }
-
- #[test]
- fn test_line_map_location() {
- let map = LineMap::new(TEST);
- assert_eq!(map.location(Pos(0)), Location::new(1, 1));
- assert_eq!(map.location(Pos(2)), Location::new(1, 2));
- assert_eq!(map.location(Pos(6)), Location::new(1, 6));
- assert_eq!(map.location(Pos(7)), Location::new(2, 1));
- assert_eq!(map.location(Pos(8)), Location::new(2, 2));
- assert_eq!(map.location(Pos(12)), Location::new(2, 3));
- assert_eq!(map.location(Pos(21)), Location::new(4, 4));
- }
-
- #[test]
- #[should_panic]
- fn test_line_map_panics_out_of_bounds() {
- LineMap::new(TEST).location(Pos(22));
- }
-}