#[cfg(feature = "lsp-responses")]
use tower_lsp_server::ls_types;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Position {
pub line: u32,
pub character: u32,
}
impl Position {
#[must_use]
pub const fn new(line: u32, character: u32) -> Self {
Self { line, character }
}
}
#[cfg(feature = "lsp-responses")]
impl From<ls_types::Position> for Position {
fn from(value: ls_types::Position) -> Self {
Self {
line: value.line,
character: value.character,
}
}
}
#[cfg(feature = "lsp-responses")]
impl From<Position> for ls_types::Position {
fn from(value: Position) -> Self {
Self::new(value.line, value.character)
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Range {
pub start: Position,
pub end: Position,
}
impl Range {
#[must_use]
pub const fn new(start: Position, end: Position) -> Self {
Self { start, end }
}
}
#[cfg(feature = "lsp-responses")]
impl From<ls_types::Range> for Range {
fn from(value: ls_types::Range) -> Self {
Self {
start: value.start.into(),
end: value.end.into(),
}
}
}
#[cfg(feature = "lsp-responses")]
impl From<Range> for ls_types::Range {
fn from(value: Range) -> Self {
Self::new(value.start.into(), value.end.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "lsp-responses")]
#[test]
fn test_position_roundtrips_through_ls_types() {
let original = Position::new(12, 34);
let ls_pos: ls_types::Position = original.into();
assert_eq!(ls_pos.line, 12);
assert_eq!(ls_pos.character, 34);
assert_eq!(Position::from(ls_pos), original);
}
#[cfg(feature = "lsp-responses")]
#[test]
fn test_range_roundtrips_through_ls_types() {
let original = Range::new(Position::new(0, 0), Position::new(2, 5));
let ls_range: ls_types::Range = original.into();
assert_eq!(ls_range.start.line, 0);
assert_eq!(ls_range.end.line, 2);
assert_eq!(Range::from(ls_range), original);
}
#[test]
fn test_range_usable_as_hashmap_key() {
use std::collections::HashMap;
let mut map: HashMap<Range, &str> = HashMap::new();
map.insert(
Range::new(Position::new(0, 0), Position::new(0, 4)),
"serde",
);
assert_eq!(
map.get(&Range::new(Position::new(0, 0), Position::new(0, 4))),
Some(&"serde")
);
}
}