1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::ops::Range;
mod convert;
pub mod iter;
#[derive(Clone, Eq, PartialEq)]
pub struct CodeView<T> {
text: String,
info: Vec<Option<T>>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct CodeSpan<T> {
pub text: String,
pub info: Option<T>,
}
impl<T> CodeView<T> {
pub fn new(text: impl Into<String>) -> Self
where
T: Clone,
{
let text = text.into();
let count = text.chars().count();
Self { text, info: vec![None; count] }
}
#[inline]
pub fn text(&self) -> &str {
&self.text
}
pub fn mark_position(&mut self, start: usize, end: usize, info: Option<T>)
where
T: Clone,
{
debug_assert!(start <= end);
let end = self.info.len().min(end);
let items = unsafe { self.info.get_unchecked_mut(Range { start, end }) };
for item in items {
*item = info.clone()
}
}
#[inline]
pub fn mark_offset(&mut self, start: usize, end: usize, info: Option<T>)
where
T: Clone,
{
let end = self.text.len().min(end);
let start = self.text[..start].chars().count();
let end = start + self.text[start..end].chars().count();
self.mark_position(start, end, info)
}
}