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 len(&self) -> usize {
143 self.slots.iter().filter(|s| s.value.is_some()).count()
144 }
145
146 pub fn clear(&mut self) {
148 let live: Vec<u32> = self
149 .slots
150 .iter()
151 .enumerate()
152 .filter(|(_, s)| s.value.is_some())
153 .map(|(i, _)| i as u32)
154 .collect();
155 for s in &mut self.slots {
156 s.value = None;
157 }
158 self.free.extend(live);
159 }
160 pub fn is_empty(&self) -> bool {
161 self.len() == 0
162 }
163}
164
165macro_rules! coordinate {
169 ($name:ident, $unit:literal) => {
170 #[derive(
171 Debug,
172 Clone,
173 Copy,
174 PartialEq,
175 Eq,
176 PartialOrd,
177 Ord,
178 Hash,
179 Default,
180 serde::Serialize,
181 serde::Deserialize,
182 )]
183 #[repr(transparent)]
184 #[serde(transparent)]
185 pub struct $name(usize);
186
187 impl $name {
188 #[inline]
189 pub fn new(v: usize) -> Self {
190 Self(v)
191 }
192 #[inline]
195 pub fn get(self) -> usize {
196 self.0
197 }
198 #[inline]
199 pub fn saturating_sub(self, n: usize) -> Self {
200 Self(self.0.saturating_sub(n))
201 }
202 }
203
204 impl std::ops::AddAssign<usize> for $name {
205 #[inline]
206 fn add_assign(&mut self, n: usize) {
207 self.0 += n;
208 }
209 }
210 impl std::ops::SubAssign<usize> for $name {
211 #[inline]
212 fn sub_assign(&mut self, n: usize) {
213 self.0 -= n;
214 }
215 }
216 impl PartialEq<usize> for $name {
219 #[inline]
220 fn eq(&self, other: &usize) -> bool {
221 self.0 == *other
222 }
223 }
224 impl PartialOrd<usize> for $name {
225 #[inline]
226 fn partial_cmp(&self, other: &usize) -> Option<std::cmp::Ordering> {
227 self.0.partial_cmp(other)
228 }
229 }
230 impl std::ops::Add<usize> for $name {
231 type Output = $name;
232 #[inline]
233 fn add(self, n: usize) -> $name {
234 $name(self.0 + n)
235 }
236 }
237 impl std::ops::Sub<usize> for $name {
238 type Output = $name;
239 #[inline]
240 fn sub(self, n: usize) -> $name {
241 $name(self.0 - n)
242 }
243 }
244 impl std::ops::Sub<$name> for $name {
245 type Output = usize; #[inline]
247 fn sub(self, other: $name) -> usize {
248 self.0 - other.0
249 }
250 }
251 impl std::fmt::Display for $name {
252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253 write!(f, "{} {}", self.0, $unit)
254 }
255 }
256 impl From<$name> for usize {
257 #[inline]
258 fn from(v: $name) -> usize {
259 v.0
260 }
261 }
262 impl From<usize> for $name {
263 #[inline]
264 fn from(v: usize) -> $name {
265 $name(v)
266 }
267 }
268 };
269}
270
271coordinate!(ByteOffset, "B");
272coordinate!(LineIndex, "L");
273coordinate!(ByteColumn, "col:B");
274coordinate!(Utf16Column, "col:u16");
275coordinate!(DisplayColumn, "col:dsp");
276
277#[derive(
279 Debug,
280 Clone,
281 Copy,
282 PartialEq,
283 Eq,
284 PartialOrd,
285 Ord,
286 Hash,
287 Default,
288 serde::Serialize,
289 serde::Deserialize,
290)]
291#[serde(transparent)]
292pub struct BufferRevision(u64);
293
294impl BufferRevision {
295 pub const fn new(value: u64) -> Self {
296 Self(value)
297 }
298 pub const fn get(self) -> u64 {
299 self.0
300 }
301 pub fn checked_next(self) -> Option<Self> {
302 self.0.checked_add(1).map(Self)
303 }
304}
305
306impl std::fmt::Display for BufferRevision {
307 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
308 self.0.fmt(formatter)
309 }
310}
311
312impl From<u64> for BufferRevision {
313 fn from(value: u64) -> Self {
314 Self(value)
315 }
316}
317
318#[cfg(test)]
325mod tests {
326 use super::*;
327
328 #[test]
329 fn stale_ids_fail_lookup() {
330 let mut a: Arena<DocumentKind, String> = Arena::default();
331 let one = a.insert("one".into());
332 let two = a.insert("two".into());
333 assert_eq!(a.get(one).map(String::as_str), Some("one"));
334 a.remove(one);
335 assert_eq!(a.get(one), None, "removed");
336 let three = a.insert("three".into()); assert_eq!(a.get(one), None, "stale generation must not resolve");
338 assert_eq!(a.get(three).map(String::as_str), Some("three"));
339 assert_eq!(a.get(two).map(String::as_str), Some("two"));
340 assert_eq!(a.len(), 2);
341 }
342}