From 6c004ba3bd9f46863abfeda25721036d444fed71 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 2 Apr 2024 18:45:59 -0400 Subject: [PATCH] WIP --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/source.rs | 24 ++++++++++++++---------- src/span.rs | 20 +++++++++++++------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bcbfd6..441be24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -413,9 +413,9 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "safe-string" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b95c754451a4a8b00011e37320894983b28dbded186ac4c8786a71a2d61f22" +checksum = "c699d55ef046e66db4508d9cb09ba1220a42e9bb5f3dac0469e266031c8fcc6e" [[package]] name = "seahash" diff --git a/Cargo.toml b/Cargo.toml index 7ddfd05..a8dd984 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,4 @@ license = "MIT" quoth-macros = { path = "quoth-macros", version = "0.1.5" } regex = "1.10" rust_decimal = "1" -safe-string = "0.1.1" +safe-string = "0.1.5" diff --git a/src/source.rs b/src/source.rs index 2f6e486..0b986cf 100644 --- a/src/source.rs +++ b/src/source.rs @@ -1,6 +1,5 @@ //! home of [`Source`] and related types. -#[cfg(doc)] use super::*; use std::{ @@ -11,14 +10,14 @@ use std::{ /// Represents source text that can be indexed into to define individual [`Span`]s. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Source { - text: String, + text: IndexedString, path: Option, } impl Source { /// Returns the underlying text of this [`Source`], with original formatting. - pub fn source_text(&self) -> &str { - &self.text + pub fn source_text(&self) -> IndexedSlice { + self.text.as_slice() } /// Returns the path of the file that this [`Source`] was read from, if it was read from a file. @@ -26,21 +25,26 @@ impl Source { self.path.as_ref().map(|path| path.as_path()) } - /// Returns the length of the underlying text of this [`Source`]. - pub fn from_str(string: impl Into) -> Self { + /// Creates a new [`Source`] from a string. + pub fn from_str(string: impl AsRef) -> Self { Source { - text: string.into(), + text: IndexedString::from_str(string.as_ref()), path: None, } } + /// Creates a new [`Source`] from an [`IndexedString`]. + pub fn from_indexed_string(text: IndexedString) -> Self { + Source { text, path: None } + } + /// Reads the contents of a file and returns a [`Source`] with the file's text. /// /// Since no parsing is done at this stage, only IO or encoding errors will be returned, /// regardless of the validity of the syntax in the file. pub fn from_file(path: impl AsRef) -> core::result::Result { std::fs::read_to_string(path.as_ref()).map(|text| Source { - text, + text: IndexedString::from(&text), path: Some(path.as_ref().to_path_buf()), }) } @@ -52,7 +56,7 @@ impl Source { } impl Deref for Source { - type Target = String; + type Target = IndexedString; fn deref(&self) -> &Self::Target { &self.text @@ -62,7 +66,7 @@ impl Deref for Source { impl From for Source { fn from(value: S) -> Self { Source { - text: value.to_string(), + text: IndexedString::from(value.to_string()), path: None, } } diff --git a/src/span.rs b/src/span.rs index c766b69..c2ad5cb 100644 --- a/src/span.rs +++ b/src/span.rs @@ -77,8 +77,8 @@ impl Span { } /// Returns the text of the [`Source`] that this [`Span`] is associated with. - pub fn source_text(&self) -> &str { - &self.source[self.byte_range.clone()] + pub fn source_text(&self) -> IndexedSlice { + self.source.slice(self.byte_range.clone()) } /// Returns the path of the [`Source`] that this [`Span`] is associated with, if it has one. @@ -99,8 +99,8 @@ impl Span { pub fn start(&self) -> LineCol { let mut line = 0; let mut col = 0; - for c in self.source[0..self.byte_range.start].chars() { - if c == '\n' { + for c in self.source.slice(0..self.byte_range.start).chars() { + if *c == '\n' { col = 0; line += 1; } else { @@ -113,8 +113,12 @@ impl Span { /// Returns the line and column of the end of this [`Span`] within the [`Source`]. pub fn end(&self) -> LineCol { let LineCol { mut line, mut col } = self.start(); - for c in self.source[self.byte_range.start..self.byte_range.end].chars() { - if c == '\n' { + for c in self + .source + .slice(self.byte_range.start..self.byte_range.end) + .chars() + { + if *c == '\n' { col = 0; line += 1; } else { @@ -125,7 +129,7 @@ impl Span { } /// Returns an iterator over the lines of the [`Source`] that this [`Span`] is associated with, - pub fn source_lines(&self) -> impl Iterator)> { + pub fn source_lines(&self) -> impl Iterator)> { let start_line_col = self.start(); let end_line_col = self.end(); let start_col = start_line_col.col; @@ -133,9 +137,11 @@ impl Span { let end_line = end_line_col.line; let end_col = end_line_col.col; self.source + .as_str() .lines() .enumerate() .filter_map(move |(i, line)| { + let line = IndexedString::from(line); if start_line == end_line && end_line == i { Some((line, start_col..end_col)) } else if i == start_line {