1#[cfg(feature = "ast-json")]
2use serde::{Deserialize, Serialize};
3use std::{marker::PhantomData, ops::Index};
4
5#[cfg_attr(feature = "ast-json", derive(Serialize, Deserialize))]
10#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct ArenaId<T> {
12 id: u32,
13 _phantom_data: PhantomData<T>,
14}
15
16impl<T> Copy for ArenaId<T> {}
17
18impl<T> Clone for ArenaId<T> {
19 #[inline(always)]
20 fn clone(&self) -> ArenaId<T> {
21 *self
22 }
23}
24
25impl<T> From<u32> for ArenaId<T> {
26 fn from(id: u32) -> Self {
27 Self::new(id)
28 }
29}
30
31impl<T> From<usize> for ArenaId<T> {
32 fn from(id: usize) -> Self {
33 Self::new(id as u32)
34 }
35}
36
37impl<T> From<i32> for ArenaId<T> {
38 fn from(id: i32) -> Self {
39 Self::new(id as u32)
40 }
41}
42
43impl<T> ArenaId<T> {
44 pub const fn new(id: u32) -> ArenaId<T> {
46 Self {
47 id,
48 _phantom_data: PhantomData,
49 }
50 }
51}
52
53#[derive(Debug, Clone, Default)]
59pub struct Arena<T> {
60 items: Vec<T>,
61}
62
63impl<T: Clone + PartialEq> Arena<T> {
64 pub fn new(size: usize) -> Self {
66 Arena {
67 items: Vec::with_capacity(size),
68 }
69 }
70
71 pub fn alloc(&mut self, value: T) -> ArenaId<T> {
73 let arena_id = self.items.len() as u32;
74 self.items.push(value);
75 ArenaId::new(arena_id)
76 }
77
78 pub fn len(&self) -> usize {
80 self.items.len()
81 }
82
83 pub fn is_empty(&self) -> bool {
85 self.len() == 0
86 }
87
88 pub fn contains(&self, value: T) -> bool {
90 self.items.contains(&value)
91 }
92}
93
94impl<T> Index<ArenaId<T>> for Arena<T> {
95 type Output = T;
96
97 fn index(&self, index: ArenaId<T>) -> &Self::Output {
98 &self.items[index.id as usize]
99 }
100}
101
102impl<T> Arena<T> {
103 pub fn get(&self, id: ArenaId<T>) -> Option<&T> {
105 self.items.get(id.id as usize)
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use rstest::rstest;
113
114 #[rstest]
115 #[case(vec![1, 2, 3], 1, true)]
116 #[case(vec![1, 2, 3], 4, false)]
117 #[case(Vec::new(), 1, false)]
118 fn test_contains(#[case] values: Vec<i32>, #[case] value: i32, #[case] expected: bool) {
119 let mut arena = Arena::new(values.len());
120 for v in values {
121 arena.alloc(v);
122 }
123 assert_eq!(arena.contains(value), expected);
124 }
125
126 #[rstest]
127 #[case(vec![1, 2, 3], 1, 2)]
128 #[case(vec![1, 2, 3], 0, 1)]
129 #[case(vec![1, 2, 3], 2, 3)]
130 fn test_get(#[case] values: Vec<i32>, #[case] index: u32, #[case] expected: i32) {
131 let mut arena = Arena::new(values.len());
132 for v in values {
133 arena.alloc(v);
134 }
135 let id = ArenaId::new(index);
136 assert_eq!(arena[id], expected);
137 }
138
139 #[rstest]
140 #[case(vec![1, 2, 3], 3)]
141 #[case(Vec::new(), 0)]
142 fn test_len(#[case] values: Vec<i32>, #[case] expected: usize) {
143 let mut arena = Arena::new(values.len());
144 for v in values {
145 arena.alloc(v);
146 }
147 assert_eq!(arena.len(), expected);
148 }
149
150 #[rstest]
151 #[case(vec![1, 2, 3], false)]
152 #[case(Vec::new(), true)]
153 fn test_is_empty(#[case] values: Vec<i32>, #[case] expected: bool) {
154 let mut arena = Arena::new(values.len());
155 for v in values {
156 arena.alloc(v);
157 }
158 assert_eq!(arena.is_empty(), expected);
159 }
160
161 #[test]
162 fn test_from() {
163 let id_u32: ArenaId<i32> = 5u32.into();
164 assert_eq!(id_u32.id, 5);
165
166 let id_usize: ArenaId<i32> = 10usize.into();
167 assert_eq!(id_usize.id, 10);
168
169 let id_i32: ArenaId<i32> = 15i32.into();
170 assert_eq!(id_i32.id, 15);
171 }
172}