1use std::{
2 cell,
3 cmp::Ordering,
4 fmt,
5 iter::repeat,
6 ops::{Bound, Range, RangeBounds},
7};
8
9use hi_doc_jumprope::{
10 iter::{Chars as RopeChars, ContentIter, SliceIter, Substrings},
11 JumpRope, JumpRopeBuf,
12};
13
14use crate::{AnnotatedRange, ApplyAnnotation};
15
16#[derive(Clone, Debug)]
17pub struct AnnotatedRope<M> {
18 rope: JumpRopeBuf,
19 annotations: AnnotatedRange<M>,
20}
21
22#[ouroboros::self_referencing]
23pub struct Fragments<'r> {
24 rope_buf: cell::Ref<'r, JumpRope>,
25 #[borrows(rope_buf)]
26 #[not_covariant]
27 iter: Substrings<'this, SliceIter<'this>>,
28}
29impl<'f> Iterator for Fragments<'f> {
30 type Item = &'f str;
31
32 fn next(&mut self) -> Option<Self::Item> {
33 let v = self.with_iter_mut(|s| s.next())?;
34
35 Some(unsafe {
42 std::str::from_utf8_unchecked(std::slice::from_raw_parts(v.as_ptr(), v.len()))
43 })
44 }
45}
46#[ouroboros::self_referencing]
47pub struct Chars<'r> {
48 rope_buf: cell::Ref<'r, JumpRope>,
49 #[borrows(rope_buf)]
50 #[covariant]
51 iter: RopeChars<'this, ContentIter<'this>>,
52}
53impl Iterator for Chars<'_> {
54 type Item = char;
55
56 fn next(&mut self) -> Option<Self::Item> {
57 self.with_iter_mut(|c| c.next())
58 }
59}
60
61fn bounds_to_exclusive(bounds: impl RangeBounds<usize>, len: usize) -> Range<usize> {
62 let start = match bounds.start_bound() {
63 Bound::Included(v) => *v,
64 Bound::Excluded(_) => unreachable!("not creatable with standard syntax"),
65 Bound::Unbounded => 0,
66 };
67 let end = match bounds.end_bound() {
68 Bound::Included(i) => i + 1,
69 Bound::Excluded(e) => *e,
70 Bound::Unbounded => len,
71 };
72 start..end
73}
74
75impl<M: Clone> AnnotatedRope<M> {
76 pub fn new() -> Self {
77 Self {
78 rope: JumpRopeBuf::new(),
79 annotations: AnnotatedRange::new(),
80 }
81 }
82 pub fn fragment(v: impl AsRef<str>, meta: M) -> Self {
83 let v: String = v.as_ref().to_string();
84 let rope: JumpRopeBuf = v.into();
85 if rope.is_empty() {
86 Self::new()
87 } else {
88 Self {
89 annotations: AnnotatedRange::with_size(rope.len_chars(), meta),
90 rope,
91 }
92 }
93 }
94 pub fn fragment_chars(v: impl IntoIterator<Item = char>, meta: M) -> Self {
95 let v: String = v.into_iter().collect();
96 let rope: JumpRopeBuf = v.into();
97 if rope.is_empty() {
98 Self::new()
99 } else {
100 Self {
101 annotations: AnnotatedRange::with_size(rope.len_chars(), meta),
102 rope,
103 }
104 }
105 }
106 #[deprecated = "use fragment_chars with repeated char"]
107 pub fn repeated_char_fragment(char: char, count: usize, meta: M) -> Self {
108 Self::fragment(char.to_string().repeat(count), meta)
109 }
110 pub fn insert(&mut self, position: usize, buf: Self) {
111 let incoming = buf.rope.borrow();
112 let mut offset = position;
113 for (str, len) in incoming.substrings_with_len() {
114 self.rope.insert(offset, str);
115 offset += len;
116 }
117 self.annotations.insert(position, buf.annotations);
118 }
119 pub fn remove(&mut self, range: impl RangeBounds<usize>) {
120 let range = bounds_to_exclusive(range, self.len());
121 self.rope.remove(range.clone());
122 self.annotations.remove(range);
123 }
124 pub fn splice(&mut self, range: impl RangeBounds<usize>, value: Option<Self>) {
125 let range = bounds_to_exclusive(range, self.len());
126 let start = range.start;
127 self.remove(range);
128 if let Some(value) = value {
129 self.insert(start, value);
130 }
131 }
132 pub fn extend(&mut self, buf: impl IntoIterator<Item = Self>) {
133 for buf in buf {
134 self.insert(self.annotations.len(), buf)
135 }
136 }
137 pub fn append(&mut self, buf: Self) {
138 self.extend([buf]);
139 }
140 pub fn fragments(&self) -> impl IntoIterator<Item = (Fragments<'_>, &'_ M)> {
141 self.annotations.iter().map(|v| {
142 (
143 Fragments::new(self.rope.borrow(), |r| r.slice_substrings(v.1)),
144 v.0,
145 )
146 })
147 }
148 pub fn len(&self) -> usize {
149 self.rope.len_chars()
150 }
151 pub fn is_empty(&self) -> bool {
152 self.rope.is_empty()
153 }
154
155 pub fn get(&self, pos: usize) -> Option<(char, &M)> {
156 self.rope
157 .borrow()
158 .slice_chars(pos..pos + 1)
159 .next()
160 .map(|v| (v, self.annotations.get(pos).expect("meta is broken?")))
161 }
162
163 pub fn chars(&self) -> Chars<'_> {
164 Chars::new(self.rope.borrow(), |v| v.chars())
165 }
166 pub fn resize(&mut self, size: usize, char: char, meta: M) {
167 match size.cmp(&self.len()) {
168 Ordering::Less => self.remove(size..),
169 Ordering::Greater => self.extend([Self::fragment_chars(
170 repeat(char).take(size - self.len()),
171 meta,
172 )]),
173 Ordering::Equal => {}
174 }
175 }
176 pub fn split_at(self, pos: usize) -> (Self, Self) {
177 let rope = self.rope.into_inner();
178 let mut left = rope.clone();
179 left.remove(pos..left.len_chars());
180 let mut right = rope;
181 right.remove(0..pos);
182
183 let meta = self.annotations.clone();
184 let (meta_left, meta_right) = meta.split(pos);
185 (
186 AnnotatedRope {
187 rope: left.into(),
188 annotations: meta_left,
189 },
190 AnnotatedRope {
191 rope: right.into(),
192 annotations: meta_right,
193 },
194 )
195 }
196 pub fn index_of(&self, char: char) -> Option<usize> {
197 self.chars().position(|v| v == char)
198 }
199 pub fn split(&self, char: char) -> Vec<Self> {
200 let mut out = Vec::new();
201 let mut v = self.clone();
202 while let Some(pos) = v.index_of(char) {
203 let (left, right) = v.split_at(pos);
204 out.push(left);
205 v = right;
206 }
207 out.push(v);
208 out
209 }
210}
211impl<M> AnnotatedRope<M> {}
212
213impl<M: Clone + fmt::Debug> Default for AnnotatedRope<M> {
214 fn default() -> Self {
215 Self::new()
216 }
217}
218impl<M: Clone + PartialEq + fmt::Debug> AnnotatedRope<M> {
219 pub fn annotate_range<T>(&mut self, range: impl RangeBounds<usize>, value: &T)
220 where
221 M: ApplyAnnotation<T>,
222 {
223 self.annotations
224 .apply_meta(bounds_to_exclusive(range, self.len()), value)
225 }
226}
227
228impl<M: Clone> FromIterator<AnnotatedRope<M>> for AnnotatedRope<M> {
229 fn from_iter<T: IntoIterator<Item = AnnotatedRope<M>>>(iter: T) -> Self {
230 let mut rope = AnnotatedRope::new();
231 rope.extend(iter);
232 rope
233 }
234}