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