Clean up visibility in span module, more tests
This commit is contained in:
parent
b7f28b32f0
commit
96d1311e09
@ -2,7 +2,7 @@ use std::{cmp::Ordering, iter, ops::Range, sync::Arc};
|
|||||||
|
|
||||||
/// A location within some source text.
|
/// A location within some source text.
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct Location {
|
pub(crate) struct Location {
|
||||||
line: usize,
|
line: usize,
|
||||||
column: usize,
|
column: usize,
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ pub struct Location {
|
|||||||
impl Location {
|
impl Location {
|
||||||
/// Construct a new instance of `Location`.
|
/// Construct a new instance of `Location`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn new(line: usize, column: usize) -> Self {
|
pub(crate) const fn new(line: usize, column: usize) -> Self {
|
||||||
Self { line, column }
|
Self { line, column }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ impl PartialOrd for Location {
|
|||||||
|
|
||||||
/// Some (optionally named) source text.
|
/// Some (optionally named) source text.
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Source {
|
pub(crate) struct Source {
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
contents: String,
|
contents: String,
|
||||||
lines: Vec<usize>,
|
lines: Vec<usize>,
|
||||||
@ -35,7 +35,7 @@ pub struct Source {
|
|||||||
impl Source {
|
impl Source {
|
||||||
/// Construct a new instance of `Source`.
|
/// Construct a new instance of `Source`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(name: Option<String>, contents: String) -> Self {
|
pub(crate) fn new(name: Option<String>, contents: String) -> Self {
|
||||||
let lines = contents
|
let lines = contents
|
||||||
.match_indices('\n')
|
.match_indices('\n')
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
@ -51,18 +51,18 @@ impl Source {
|
|||||||
|
|
||||||
/// Get the name of the source.
|
/// Get the name of the source.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn name(&self) -> Option<&str> {
|
pub(crate) fn name(&self) -> Option<&str> {
|
||||||
self.name.as_deref()
|
self.name.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the name of the source.
|
/// 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);
|
self.name = Some(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the [Location] of the specified byte in the source.
|
/// Get the [Location] of the specified byte in the source.
|
||||||
#[must_use]
|
#[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 line = self.lines.partition_point(|&x| x < byte);
|
||||||
let start = line.checked_sub(1).map_or(0, |n| self.lines[n] + 1);
|
let start = line.checked_sub(1).map_or(0, |n| self.lines[n] + 1);
|
||||||
let column = self.contents[start..byte].chars().count();
|
let column = self.contents[start..byte].chars().count();
|
||||||
@ -72,13 +72,13 @@ impl Source {
|
|||||||
|
|
||||||
/// Get the full contents of the source.
|
/// Get the full contents of the source.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contents(&self) -> &str {
|
pub(crate) fn contents(&self) -> &str {
|
||||||
&self.contents
|
&self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the specified line from the source.
|
/// Get the specified line from the source.
|
||||||
#[must_use]
|
#[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 end = self.lines[line];
|
||||||
let start = line.checked_sub(1).map_or(0, |n| self.lines[n] + 1);
|
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.
|
/// A contiguous sequence of bytes within some source.
|
||||||
#[derive(Debug, Default, Clone, Eq, Hash)]
|
#[derive(Debug, Default, Clone, Eq, Hash)]
|
||||||
pub struct Span {
|
pub(crate) struct Span {
|
||||||
bytes: Range<usize>,
|
bytes: Range<usize>,
|
||||||
source: Arc<Source>,
|
source: Arc<Source>,
|
||||||
}
|
}
|
||||||
@ -96,39 +96,39 @@ pub struct Span {
|
|||||||
impl Span {
|
impl Span {
|
||||||
/// Construct a new instance of `Span`.
|
/// Construct a new instance of `Span`.
|
||||||
#[must_use]
|
#[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 }
|
Self { bytes, source }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join two spans, creating a new span.
|
/// Join two spans, creating a new span.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn join(self, other: &Self) -> Self {
|
pub(crate) fn join(self, other: &Self) -> Self {
|
||||||
debug_assert!(self.same_source(other));
|
debug_assert!(self.same_source(other));
|
||||||
|
|
||||||
Self::new(self.bytes.start..other.bytes.end, self.source)
|
Self::new(self.bytes.start..other.bytes.end, self.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend one span to include another.
|
/// 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));
|
debug_assert!(self.same_source(other));
|
||||||
self.bytes.end = other.bytes.end;
|
self.bytes.end = other.bytes.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The start location of a span within some source.
|
/// The start location of a span within some source.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn location(&self) -> Location {
|
pub(crate) fn location(&self) -> Location {
|
||||||
self.source.location(self.bytes.start)
|
self.source.location(self.bytes.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The end location of a span within some source.
|
/// The end location of a span within some source.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn end_location(&self) -> Location {
|
pub(crate) fn end_location(&self) -> Location {
|
||||||
self.source.location(self.bytes.end)
|
self.source.location(self.bytes.end)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do two spans share the same source?
|
/// Do two spans share the same source?
|
||||||
#[must_use]
|
#[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)
|
Arc::ptr_eq(&self.source, &other.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,4 +164,27 @@ mod tests {
|
|||||||
src.set_name("foo".into());
|
src.set_name("foo".into());
|
||||||
assert!(src.name() == Some("foo"));
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user