eww/crates/eww_shared_util/src/span.rs
2023-02-25 16:27:32 +01:00

75 lines
2 KiB
Rust

/// A span is made up of
/// - the start location
/// - the end location
/// - the file id
#[derive(Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
pub struct Span(pub usize, pub usize, pub usize);
impl Span {
pub const DUMMY: Span = Span(usize::MAX, usize::MAX, usize::MAX);
pub fn point(loc: usize, file_id: usize) -> Self {
Span(loc, loc, file_id)
}
/// Get the span that includes this and the other span completely.
/// Will panic if the spans are from different file_ids.
pub fn to(mut self, other: Span) -> Self {
assert!(other.2 == self.2);
self.1 = other.1;
self
}
pub fn ending_at(mut self, end: usize) -> Self {
self.1 = end;
self
}
/// Turn this span into a span only highlighting the point it starts at, setting the length to 0.
pub fn point_span(mut self) -> Self {
self.1 = self.0;
self
}
/// Turn this span into a span only highlighting the point it ends at, setting the length to 0.
pub fn point_span_at_end(mut self) -> Self {
self.0 = self.1;
self
}
pub fn shifted(mut self, n: isize) -> Self {
self.0 = isize::max(0, self.0 as isize + n) as usize;
self.1 = isize::max(0, self.0 as isize + n) as usize;
self
}
pub fn new_relative(mut self, other_start: usize, other_end: usize) -> Self {
self.0 += other_start;
self.1 += other_end;
self
}
pub fn is_dummy(&self) -> bool {
*self == Self::DUMMY
}
}
impl std::fmt::Display for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.is_dummy() {
write!(f, "DUMMY")
} else {
write!(f, "{}..{}", self.0, self.1)
}
}
}
impl std::fmt::Debug for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}
pub trait Spanned {
fn span(&self) -> Span;
}