#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Position {
pub line: u32,
pub column: u32,
}
impl Position {
pub const fn missing() -> Self {
Self {
line: u32::MAX,
column: u32::MAX,
}
}
pub const fn zero() -> Self {
Self { line: 0, column: 0 }
}
pub const fn new(line: u32, column: u32) -> Self {
Self { line, column }
}
pub const fn has_value(self) -> bool {
self.line != u32::MAX || self.column != u32::MAX
}
pub fn shift(&mut self, start: Position, old_end: Position, new_end: Position) {
if *self >= start {
if self.line > old_end.line {
self.line = self
.line
.wrapping_add(new_end.line.wrapping_sub(old_end.line));
} else {
self.line = new_end.line;
self.column = self
.column
.wrapping_add(new_end.column.wrapping_sub(old_end.column));
}
}
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Location {
pub begin: Position,
pub end: Position,
}
impl Location {
pub const fn zero() -> Self {
Self {
begin: Position::zero(),
end: Position::zero(),
}
}
pub const fn new(begin: Position, end: Position) -> Self {
Self { begin, end }
}
pub const fn from_length(begin: Position, length: u32) -> Self {
Self {
begin,
end: Position {
line: begin.line,
column: begin.column + length,
},
}
}
pub const fn spanning(begin: Location, end: Location) -> Self {
Self {
begin: begin.begin,
end: end.end,
}
}
pub fn encloses(self, location: Location) -> bool {
self.begin <= location.begin && self.end >= location.end
}
pub fn overlaps(self, location: Location) -> bool {
(self.begin <= location.begin && self.end >= location.begin)
|| (self.begin <= location.end && self.end >= location.end)
|| (self.begin >= location.begin && self.end <= location.end)
}
pub fn contains(self, position: Position) -> bool {
self.begin <= position && position < self.end
}
pub fn contains_closed(self, position: Position) -> bool {
self.begin <= position && position <= self.end
}
pub fn extend(&mut self, other: Location) {
if other.begin < self.begin {
self.begin = other.begin;
}
if other.end > self.end {
self.end = other.end;
}
}
pub fn shift(&mut self, start: Position, old_end: Position, new_end: Position) {
self.begin.shift(start, old_end, new_end);
self.end.shift(start, old_end, new_end);
}
}