1use std::{
2 cell,
3 cmp::Ordering,
4 fmt,
5 iter::repeat_n,
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 + Default> AnnotatedRope<M> {
76 pub fn default_fragment(v: impl AsRef<str>) -> Self {
77 Self::fragment(v, M::default())
78 }
79}
80
81impl<M: Clone> AnnotatedRope<M> {
82 pub fn new() -> Self {
83 Self {
84 rope: JumpRopeBuf::new(),
85 annotations: AnnotatedRange::new(),
86 }
87 }
88 pub fn fragment(v: impl AsRef<str>, meta: M) -> Self {
89 let v: String = v.as_ref().to_string();
90 let rope: JumpRopeBuf = v.into();
91 if rope.is_empty() {
92 Self::new()
93 } else {
94 Self {
95 annotations: AnnotatedRange::with_size(rope.len_chars(), meta),
96 rope,
97 }
98 }
99 }
100 pub fn fragment_chars(v: impl IntoIterator<Item = char>, meta: M) -> Self {
101 let v: String = v.into_iter().collect();
102 let rope: JumpRopeBuf = v.into();
103 if rope.is_empty() {
104 Self::new()
105 } else {
106 Self {
107 annotations: AnnotatedRange::with_size(rope.len_chars(), meta),
108 rope,
109 }
110 }
111 }
112 #[deprecated = "use fragment_chars with repeated char"]
113 pub fn repeated_char_fragment(char: char, count: usize, meta: M) -> Self {
114 Self::fragment(char.to_string().repeat(count), meta)
115 }
116 pub fn insert(&mut self, position: usize, buf: Self) {
117 let incoming = buf.rope.borrow();
118 let mut offset = position;
119 for (str, len) in incoming.substrings_with_len() {
120 self.rope.insert(offset, str);
121 offset += len;
122 }
123 self.annotations.insert(position, buf.annotations);
124 }
125 pub fn remove(&mut self, range: impl RangeBounds<usize>) {
126 let range = bounds_to_exclusive(range, self.len());
127 self.rope.remove(range.clone());
128 self.annotations.remove(range);
129 }
130 pub fn splice(&mut self, range: impl RangeBounds<usize>, value: Option<Self>) {
131 let range = bounds_to_exclusive(range, self.len());
132 let start = range.start;
133 self.remove(range);
134 if let Some(value) = value {
135 self.insert(start, value);
136 }
137 }
138 pub fn extend(&mut self, buf: impl IntoIterator<Item = Self>) {
139 for buf in buf {
140 self.insert(self.annotations.len(), buf)
141 }
142 }
143 pub fn append(&mut self, buf: Self) {
144 self.extend([buf]);
145 }
146 pub fn fragments(&self) -> impl IntoIterator<Item = (Fragments<'_>, &'_ M)> {
147 self.annotations.iter().map(|v| {
148 (
149 Fragments::new(self.rope.borrow(), |r| r.slice_substrings(v.1)),
150 v.0,
151 )
152 })
153 }
154 pub fn len(&self) -> usize {
155 self.rope.len_chars()
156 }
157 pub fn is_empty(&self) -> bool {
158 self.rope.is_empty()
159 }
160
161 pub fn get(&self, pos: usize) -> Option<(char, &M)> {
162 self.rope
163 .borrow()
164 .slice_chars(pos..pos + 1)
165 .next()
166 .map(|v| (v, self.annotations.get(pos).expect("meta is broken?")))
167 }
168
169 pub fn chars(&self) -> Chars<'_> {
170 Chars::new(self.rope.borrow(), |v| v.chars())
171 }
172 pub fn resize(&mut self, size: usize, char: char, meta: M) {
173 match size.cmp(&self.len()) {
174 Ordering::Less => self.remove(size..),
175 Ordering::Greater => self.extend([Self::fragment_chars(
176 repeat_n(char, size - self.len()),
177 meta,
178 )]),
179 Ordering::Equal => {}
180 }
181 }
182 pub fn split_at(self, pos: usize) -> (Self, Self) {
183 let rope = self.rope.into_inner();
184 let mut left = rope.clone();
185 left.remove(pos..left.len_chars());
186 let mut right = rope;
187 right.remove(0..pos);
188
189 let meta = self.annotations.clone();
190 let (meta_left, meta_right) = meta.split(pos);
191 (
192 AnnotatedRope {
193 rope: left.into(),
194 annotations: meta_left,
195 },
196 AnnotatedRope {
197 rope: right.into(),
198 annotations: meta_right,
199 },
200 )
201 }
202 pub fn index_of(&self, char: char) -> Option<usize> {
203 self.chars().position(|v| v == char)
204 }
205 pub fn split(&self, char: char) -> Vec<Self> {
206 let mut out = Vec::new();
207 let mut v = self.clone();
208 while let Some(pos) = v.index_of(char) {
209 let (left, right) = v.split_at(pos);
210 out.push(left);
211 v = right;
212 }
213 out.push(v);
214 out
215 }
216}
217impl<M> AnnotatedRope<M> {}
218
219impl<M: Clone + fmt::Debug> Default for AnnotatedRope<M> {
220 fn default() -> Self {
221 Self::new()
222 }
223}
224impl<M: Clone + PartialEq + fmt::Debug> AnnotatedRope<M> {
225 pub fn annotate_range<T>(&mut self, range: impl RangeBounds<usize>, value: &T)
226 where
227 M: ApplyAnnotation<T>,
228 {
229 self.annotations
230 .apply_meta(bounds_to_exclusive(range, self.len()), value)
231 }
232}
233
234impl<M: Clone> FromIterator<AnnotatedRope<M>> for AnnotatedRope<M> {
235 fn from_iter<T: IntoIterator<Item = AnnotatedRope<M>>>(iter: T) -> Self {
236 let mut rope = AnnotatedRope::new();
237 rope.extend(iter);
238 rope
239 }
240}