annotated_string/
rope.rs

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		// Safety: this str is located in rope_buf, yet it isn't
36		// possible to explain this to jumprope
37		//
38		// This value will live as long as parent ropebuf, because
39		// the iterator itself has a lock on jumprope (Ref), and
40		// the string is borrowed from ouroboros.
41		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}