Clean up visibility in span module, more tests

This commit is contained in:
Jesse Braham 2024-12-20 21:15:47 +01:00
parent b7f28b32f0
commit 96d1311e09

View File

@ -2,7 +2,7 @@ use std::{cmp::Ordering, iter, ops::Range, sync::Arc};
/// A location within some source text.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Location {
pub(crate) struct Location {
line: usize,
column: usize,
}
@ -10,7 +10,7 @@ pub struct Location {
impl Location {
/// Construct a new instance of `Location`.
#[must_use]
pub const fn new(line: usize, column: usize) -> Self {
pub(crate) const fn new(line: usize, column: usize) -> Self {
Self { line, column }
}
}
@ -26,7 +26,7 @@ impl PartialOrd for Location {
/// Some (optionally named) source text.
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct Source {
pub(crate) struct Source {
name: Option<String>,
contents: String,
lines: Vec<usize>,
@ -35,7 +35,7 @@ pub struct Source {
impl Source {
/// Construct a new instance of `Source`.
#[must_use]
pub fn new(name: Option<String>, contents: String) -> Self {
pub(crate) fn new(name: Option<String>, contents: String) -> Self {
let lines = contents
.match_indices('\n')
.map(|(i, _)| i)
@ -51,18 +51,18 @@ impl Source {
/// Get the name of the source.
#[must_use]
pub fn name(&self) -> Option<&str> {
pub(crate) fn name(&self) -> Option<&str> {
self.name.as_deref()
}
/// Set the name of the source.
pub fn set_name(&mut self, name: String) {
pub(crate) fn set_name(&mut self, name: String) {
self.name = Some(name);
}
/// Get the [Location] of the specified byte in the source.
#[must_use]
pub fn location(&self, byte: usize) -> Location {
pub(crate) fn location(&self, byte: usize) -> Location {
let line = self.lines.partition_point(|&x| x < byte);
let start = line.checked_sub(1).map_or(0, |n| self.lines[n] + 1);
let column = self.contents[start..byte].chars().count();
@ -72,13 +72,13 @@ impl Source {
/// Get the full contents of the source.
#[must_use]
pub fn contents(&self) -> &str {
pub(crate) fn contents(&self) -> &str {
&self.contents
}
/// Get the specified line from the source.
#[must_use]
pub fn get_line(&self, line: usize) -> &str {
pub(crate) fn get_line(&self, line: usize) -> &str {
let end = self.lines[line];
let start = line.checked_sub(1).map_or(0, |n| self.lines[n] + 1);
@ -88,7 +88,7 @@ impl Source {
/// A contiguous sequence of bytes within some source.
#[derive(Debug, Default, Clone, Eq, Hash)]
pub struct Span {
pub(crate) struct Span {
bytes: Range<usize>,
source: Arc<Source>,
}
@ -96,39 +96,39 @@ pub struct Span {
impl Span {
/// Construct a new instance of `Span`.
#[must_use]
pub fn new(bytes: Range<usize>, source: Arc<Source>) -> Self {
pub(crate) fn new(bytes: Range<usize>, source: Arc<Source>) -> Self {
Self { bytes, source }
}
/// Join two spans, creating a new span.
#[must_use]
pub fn join(self, other: &Self) -> Self {
pub(crate) fn join(self, other: &Self) -> Self {
debug_assert!(self.same_source(other));
Self::new(self.bytes.start..other.bytes.end, self.source)
}
/// Extend one span to include another.
pub fn extend(&mut self, other: &Self) {
pub(crate) fn extend(&mut self, other: &Self) {
debug_assert!(self.same_source(other));
self.bytes.end = other.bytes.end;
}
/// The start location of a span within some source.
#[must_use]
pub fn location(&self) -> Location {
pub(crate) fn location(&self) -> Location {
self.source.location(self.bytes.start)
}
/// The end location of a span within some source.
#[must_use]
pub fn end_location(&self) -> Location {
pub(crate) fn end_location(&self) -> Location {
self.source.location(self.bytes.end)
}
/// Do two spans share the same source?
#[must_use]
pub fn same_source(&self, other: &Self) -> bool {
pub(crate) fn same_source(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.source, &other.source)
}
@ -164,4 +164,27 @@ mod tests {
src.set_name("foo".into());
assert!(src.name() == Some("foo"));
}
#[test]
fn source_location() {
let source = Source::new(None, "foo\nbar\nbaz".into());
assert_eq!(source.location(0), Location::new(0, 0));
assert_eq!(source.location(5), Location::new(1, 1));
assert_eq!(source.location(10), Location::new(2, 2));
}
#[test]
fn source_contents() {
let contents = String::from("xxx");
let source = Source::new(None, contents.clone());
assert_eq!(source.contents(), &contents);
}
#[test]
fn source_get_line() {
let source = Source::new(None, "line 1\nline 2\nline 3\n".into());
assert_eq!(source.get_line(0), "line 1");
assert_eq!(source.get_line(1), "line 2");
assert_eq!(source.get_line(2), "line 3");
}
}