1use crate::{SourceText, source::Source};
2use lsp_types::Position;
3use std::range::Range;
4
5#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11pub struct SourceView<'view> {
12 pub(crate) source: &'view SourceText,
13 pub(crate) range: Range<usize>,
14}
15
16impl<'view> From<&'view SourceText> for SourceView<'view> {
17 fn from(value: &'view SourceText) -> Self {
18 Self { source: value, range: Range { start: 0, end: value.len() } }
19 }
20}
21
22impl<'view> Source for SourceView<'view> {
23 fn length(&self) -> usize {
24 self.range.end.saturating_sub(self.range.start)
25 }
26
27 fn get_text_in(&self, range: Range<usize>) -> &str {
28 let start = self.range.start + range.start;
30 let end = self.range.start + range.end;
31
32 let end = end.min(self.range.end);
34
35 self.source.get_text_in((start..end).into())
36 }
37
38 fn offset_to_position(&self, offset: usize) -> Position {
39 let source_offset = self.range.start + offset;
41 self.source.offset_to_position(source_offset)
42 }
43
44 fn position_to_offset(&self, position: Position) -> usize {
45 let source_offset = self.source.position_to_offset(position);
47 source_offset.saturating_sub(self.range.start)
48 }
49}
50
51impl<'view> SourceView<'view> {
52 pub fn view(&self, range: Range<usize>) -> Self {
65 let start = self.range.start + range.start;
66 let end = self.range.start + range.end;
67 Self { source: self.source, range: Range { start, end } }
68 }
69}