1mod seed;
11pub use seed::{ArenaSeed, ArenaSeedError};
12
13#[derive(
16 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
17)]
18#[serde(bound = "")]
19pub struct Id<K> {
20 #[serde(rename = "slot", alias = "index")]
21 index: u32,
22 generation: u32,
23 #[serde(skip)]
24 _kind: std::marker::PhantomData<K>,
25}
26
27impl<K> Id<K> {
28 pub fn index(self) -> usize {
29 self.index as usize
30 }
31
32 pub fn generation(self) -> u32 {
33 self.generation
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct DocumentKind;
40#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
41pub struct ViewKind;
42#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct PaneKind;
44#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
46pub struct WorkspaceKind;
47
48pub type DocumentId = Id<DocumentKind>;
49pub type ViewId = Id<ViewKind>;
50pub type PaneId = Id<PaneKind>;
51pub type WorkspaceId = Id<WorkspaceKind>;
52
53pub struct Arena<K, T> {
56 slots: Vec<Slot<T>>,
57 free: Vec<u32>,
58 _kind: std::marker::PhantomData<K>,
59}
60
61#[derive(Debug)]
62struct Slot<T> {
63 generation: u32,
64 value: Option<T>,
65}
66
67impl<K, T> Default for Arena<K, T> {
68 fn default() -> Self {
69 Self {
70 slots: Vec::new(),
71 free: Vec::new(),
72 _kind: std::marker::PhantomData,
73 }
74 }
75}
76
77impl<K, T> Arena<K, T> {
78 pub fn insert(&mut self, value: T) -> Id<K> {
79 if let Some(index) = self.free.pop() {
80 let slot = &mut self.slots[index as usize];
81 slot.generation += 1;
82 slot.value = Some(value);
83 return Id {
84 index,
85 generation: slot.generation,
86 _kind: std::marker::PhantomData,
87 };
88 }
89 let index = self.slots.len() as u32;
90 self.slots.push(Slot {
91 generation: 0,
92 value: Some(value),
93 });
94 Id {
95 index,
96 generation: 0,
97 _kind: std::marker::PhantomData,
98 }
99 }
100
101 pub fn get(&self, id: Id<K>) -> Option<&T> {
103 self.slots
104 .get(id.index as usize)
105 .filter(|s| s.generation == id.generation)
106 .and_then(|s| s.value.as_ref())
107 }
108
109 pub fn get_mut(&mut self, id: Id<K>) -> Option<&mut T> {
110 self.slots
111 .get_mut(id.index as usize)
112 .filter(|s| s.generation == id.generation)
113 .and_then(|s| s.value.as_mut())
114 }
115
116 pub fn remove(&mut self, id: Id<K>) -> Option<T> {
118 let slot = self.slots.get_mut(id.index as usize)?;
119 if slot.generation != id.generation {
120 return None;
121 }
122 let value = slot.value.take()?;
123 self.free.push(id.index);
124 Some(value)
125 }
126
127 pub fn iter(&self) -> impl Iterator<Item = (Id<K>, &T)> {
128 self.slots.iter().enumerate().filter_map(|(i, s)| {
129 s.value.as_ref().map(|v| {
130 (
131 Id {
132 index: i as u32,
133 generation: s.generation,
134 _kind: std::marker::PhantomData,
135 },
136 v,
137 )
138 })
139 })
140 }
141
142 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
144 self.slots.iter_mut().filter_map(|slot| slot.value.as_mut())
145 }
146
147 pub fn len(&self) -> usize {
148 self.slots.iter().filter(|s| s.value.is_some()).count()
149 }
150
151 pub fn clear(&mut self) {
153 let live: Vec<u32> = self
154 .slots
155 .iter()
156 .enumerate()
157 .filter(|(_, s)| s.value.is_some())
158 .map(|(i, _)| i as u32)
159 .collect();
160 for s in &mut self.slots {
161 s.value = None;
162 }
163 self.free.extend(live);
164 }
165 pub fn is_empty(&self) -> bool {
166 self.len() == 0
167 }
168}
169
170macro_rules! coordinate {
174 ($name:ident, $unit:literal) => {
175 #[derive(
176 Debug,
177 Clone,
178 Copy,
179 PartialEq,
180 Eq,
181 PartialOrd,
182 Ord,
183 Hash,
184 Default,
185 serde::Serialize,
186 serde::Deserialize,
187 )]
188 #[repr(transparent)]
189 #[serde(transparent)]
190 pub struct $name(usize);
191
192 impl $name {
193 #[inline]
194 pub fn new(v: usize) -> Self {
195 Self(v)
196 }
197 #[inline]
200 pub fn get(self) -> usize {
201 self.0
202 }
203 #[inline]
204 pub fn saturating_sub(self, n: usize) -> Self {
205 Self(self.0.saturating_sub(n))
206 }
207 }
208
209 impl std::ops::AddAssign<usize> for $name {
210 #[inline]
211 fn add_assign(&mut self, n: usize) {
212 self.0 += n;
213 }
214 }
215 impl std::ops::SubAssign<usize> for $name {
216 #[inline]
217 fn sub_assign(&mut self, n: usize) {
218 self.0 -= n;
219 }
220 }
221 impl PartialEq<usize> for $name {
224 #[inline]
225 fn eq(&self, other: &usize) -> bool {
226 self.0 == *other
227 }
228 }
229 impl PartialOrd<usize> for $name {
230 #[inline]
231 fn partial_cmp(&self, other: &usize) -> Option<std::cmp::Ordering> {
232 self.0.partial_cmp(other)
233 }
234 }
235 impl std::ops::Add<usize> for $name {
236 type Output = $name;
237 #[inline]
238 fn add(self, n: usize) -> $name {
239 $name(self.0 + n)
240 }
241 }
242 impl std::ops::Sub<usize> for $name {
243 type Output = $name;
244 #[inline]
245 fn sub(self, n: usize) -> $name {
246 $name(self.0 - n)
247 }
248 }
249 impl std::ops::Sub<$name> for $name {
250 type Output = usize; #[inline]
252 fn sub(self, other: $name) -> usize {
253 self.0 - other.0
254 }
255 }
256 impl std::fmt::Display for $name {
257 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258 write!(f, "{} {}", self.0, $unit)
259 }
260 }
261 impl From<$name> for usize {
262 #[inline]
263 fn from(v: $name) -> usize {
264 v.0
265 }
266 }
267 impl From<usize> for $name {
268 #[inline]
269 fn from(v: usize) -> $name {
270 $name(v)
271 }
272 }
273 };
274}
275
276coordinate!(ByteOffset, "B");
277coordinate!(LineIndex, "L");
278coordinate!(ByteColumn, "col:B");
279coordinate!(Utf16Column, "col:u16");
280coordinate!(DisplayColumn, "col:dsp");
281
282#[derive(
284 Debug,
285 Clone,
286 Copy,
287 PartialEq,
288 Eq,
289 PartialOrd,
290 Ord,
291 Hash,
292 Default,
293 serde::Serialize,
294 serde::Deserialize,
295)]
296#[serde(transparent)]
297pub struct BufferRevision(u64);
298
299impl BufferRevision {
300 pub const fn new(value: u64) -> Self {
301 Self(value)
302 }
303 pub const fn get(self) -> u64 {
304 self.0
305 }
306 pub fn checked_next(self) -> Option<Self> {
307 self.0.checked_add(1).map(Self)
308 }
309}
310
311impl std::fmt::Display for BufferRevision {
312 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
313 self.0.fmt(formatter)
314 }
315}
316
317impl From<u64> for BufferRevision {
318 fn from(value: u64) -> Self {
319 Self(value)
320 }
321}
322
323#[cfg(test)]
330mod tests {
331 use super::*;
332
333 #[test]
334 fn stale_ids_fail_lookup() {
335 let mut a: Arena<DocumentKind, String> = Arena::default();
336 let one = a.insert("one".into());
337 let two = a.insert("two".into());
338 assert_eq!(a.get(one).map(String::as_str), Some("one"));
339 a.remove(one);
340 assert_eq!(a.get(one), None, "removed");
341 let three = a.insert("three".into()); assert_eq!(a.get(one), None, "stale generation must not resolve");
343 assert_eq!(a.get(three).map(String::as_str), Some("three"));
344 assert_eq!(a.get(two).map(String::as_str), Some("two"));
345 assert_eq!(a.len(), 2);
346 }
347}