use crate::parol_ls_grammar::OwnedToken;
use derive_new::new;
use lsp_types::Range;
use crate::utils::location_to_range;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, new)]
pub(crate) struct Rng(pub(crate) Range);
impl Rng {
pub(crate) fn is_empty(&self) -> bool {
self.0.start.line == 0
&& self.0.start.character == 0
&& self.0.end.line == 0
&& self.0.end.character == 0
}
pub(crate) fn extend(mut self, right: Rng) -> Rng {
if self.is_empty() {
right
} else if right.is_empty() {
self
} else {
debug_assert!(self.0.start <= right.0.end);
self.0.end = right.0.end;
self
}
}
pub(crate) fn from_slice<'a, T>(slc: &'a [T]) -> Self
where
&'a T: Into<Rng>,
{
if slc.is_empty() {
Rng::default()
} else {
let first: &T = slc.first().unwrap();
let rng: Rng = first.into();
let last: &T = slc.last().unwrap();
rng.extend(last.into())
}
}
}
impl From<&OwnedToken> for Rng {
fn from(t: &OwnedToken) -> Self {
Self(location_to_range(&t.location))
}
}
impl From<Rng> for Range {
fn from(val: Rng) -> Self {
val.0
}
}
impl From<&Rng> for Range {
fn from(val: &Rng) -> Self {
val.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use lsp_types::{Position, Range};
#[test]
fn test_extend() {
let rng1 = Rng::new(Range {
start: Position::new(0, 0),
end: Position::new(0, 5),
});
let rng2 = Rng::new(Range {
start: Position::new(0, 12),
end: Position::new(0, 15),
});
let extended_rng = Rng::new(Range {
start: Position::new(0, 0),
end: Position::new(0, 15),
});
assert_eq!(extended_rng, rng1.extend(rng2));
let empty_rng = Rng::default();
assert!(empty_rng.is_empty());
assert_eq!(empty_rng, empty_rng.extend(empty_rng));
assert_eq!(rng1, empty_rng.extend(rng1));
assert_eq!(rng1, rng1.extend(empty_rng));
}
}