merman_editor_core/
snapshot.rs1use crate::types::{DocumentKind, DocumentUri, Position};
2use merman_analysis::{
3 FenceDelimiter, FenceTextIndex, SharedTextSlice, SourceDescriptor, SourceMap,
4};
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
8pub struct DocumentSnapshot {
9 pub uri: DocumentUri,
10 pub version: i32,
11 pub kind: DocumentKind,
12 pub source: SourceDescriptor,
13 pub text: Arc<str>,
14 pub source_map: SourceMap,
15 pub fences: Vec<FenceSnapshot>,
16}
17
18#[derive(Debug, Clone)]
19pub struct FenceSnapshot {
20 pub source_id: String,
21 pub index: usize,
22 pub source: SourceDescriptor,
23 pub start: usize,
24 pub body_start: usize,
25 pub body_end: usize,
26 pub end: usize,
27 pub text: SharedTextSlice,
28 pub fence_delimiter: Option<FenceDelimiter>,
29 pub diagram_type: Option<String>,
30 pub text_index: FenceTextIndex,
31}
32
33impl DocumentSnapshot {
34 pub fn byte_offset_for_position(&self, position: Position) -> Option<usize> {
35 self.source_map
36 .byte_offset_for_utf16_position(merman_analysis::Utf16Position {
37 line: position.line,
38 character: position.character,
39 })
40 }
41
42 pub fn fence_at_position(&self, position: Position) -> Option<&FenceSnapshot> {
43 let offset = self.byte_offset_for_position(position)?;
44
45 self.fences
46 .iter()
47 .find(|fence| fence.includes_document_offset(offset))
48 }
49}
50
51impl FenceSnapshot {
52 fn includes_document_offset(&self, offset: usize) -> bool {
53 if offset < self.start {
54 return false;
55 }
56 offset < self.end || (offset == self.end && self.includes_end_offset())
57 }
58
59 fn includes_end_offset(&self) -> bool {
60 self.fence_delimiter.is_none() || self.end == self.body_end
61 }
62}