1use std::ops::Index;
5use std::vec::Vec;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[cfg_attr(
14 feature = "serde",
15 serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>"))
16)]
17pub struct NeoArray<T> {
18 data: Vec<T>,
19}
20
21impl<T> NeoArray<T> {
22 pub fn new() -> Self {
23 Self { data: Vec::new() }
24 }
25
26 pub fn with_capacity(capacity: usize) -> Self {
27 Self {
28 data: Vec::with_capacity(capacity),
29 }
30 }
31
32 pub fn from_vec(data: Vec<T>) -> Self {
33 Self { data }
34 }
35
36 pub fn push(&mut self, item: T) {
37 self.data.push(item);
38 }
39
40 pub fn pop(&mut self) -> Option<T> {
41 self.data.pop()
42 }
43
44 pub fn len(&self) -> usize {
45 self.data.len()
46 }
47
48 pub fn is_empty(&self) -> bool {
49 self.data.is_empty()
50 }
51
52 pub fn get(&self, index: usize) -> Option<&T> {
53 self.data.get(index)
54 }
55
56 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
57 self.data.get_mut(index)
58 }
59
60 pub fn iter(&self) -> impl Iterator<Item = &T> {
61 self.data.iter()
62 }
63}
64
65impl<T> Default for NeoArray<T> {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71impl<T> From<Vec<T>> for NeoArray<T> {
72 fn from(data: Vec<T>) -> Self {
73 Self { data }
74 }
75}
76
77impl<T> FromIterator<T> for NeoArray<T> {
78 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
79 Self {
80 data: Vec::from_iter(iter),
81 }
82 }
83}
84
85impl<T> Extend<T> for NeoArray<T> {
86 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
87 self.data.extend(iter);
88 }
89}
90
91impl<T> Index<usize> for NeoArray<T> {
92 type Output = T;
93 fn index(&self, index: usize) -> &T {
94 &self.data[index]
95 }
96}
97
98impl<T> IntoIterator for NeoArray<T> {
99 type Item = T;
100 type IntoIter = std::vec::IntoIter<T>;
101 fn into_iter(self) -> Self::IntoIter {
102 self.data.into_iter()
103 }
104}
105
106impl<'a, T> IntoIterator for &'a NeoArray<T> {
107 type Item = &'a T;
108 type IntoIter = std::slice::Iter<'a, T>;
109 fn into_iter(self) -> Self::IntoIter {
110 self.data.iter()
111 }
112}
113
114impl<T: PartialEq> PartialEq<Vec<T>> for NeoArray<T> {
115 fn eq(&self, other: &Vec<T>) -> bool {
116 self.data == *other
117 }
118}
119
120impl<T: PartialEq> PartialEq<NeoArray<T>> for Vec<T> {
121 fn eq(&self, other: &NeoArray<T>) -> bool {
122 *self == other.data
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128pub struct ArrayFullError {
129 pub current_len: usize,
131}
132
133impl core::fmt::Display for ArrayFullError {
134 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135 write!(
136 f,
137 "NeoArray is full (current_len = {}; MAX_SIZE = {})",
138 self.current_len,
139 crate::MAX_STACK_SIZE
140 )
141 }
142}
143
144impl std::error::Error for ArrayFullError {}
145
146impl<T> NeoArray<T> {
147 pub const MAX_SIZE: usize = crate::MAX_STACK_SIZE;
152
153 pub fn try_push(&mut self, item: T) -> Result<(), ArrayFullError> {
158 if self.data.len() >= Self::MAX_SIZE {
159 return Err(ArrayFullError {
160 current_len: self.data.len(),
161 });
162 }
163 self.data.push(item);
164 Ok(())
165 }
166
167 pub fn remaining_capacity(&self) -> usize {
170 Self::MAX_SIZE.saturating_sub(self.data.len())
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177
178 const MAX_SIZE: usize = NeoArray::<u32>::MAX_SIZE;
179
180 #[test]
181 fn max_size_tracks_single_source() {
182 assert_eq!(NeoArray::<u32>::MAX_SIZE, crate::MAX_STACK_SIZE);
183 }
184
185 #[test]
186 fn try_push_within_limit() {
187 let mut arr: NeoArray<u32> = NeoArray::new();
188 for i in 0..100 {
189 arr.try_push(i).expect("well under MAX_SIZE");
190 }
191 assert_eq!(arr.len(), 100);
192 assert_eq!(arr.remaining_capacity(), MAX_SIZE - 100);
193 }
194
195 #[test]
196 fn try_push_at_limit_returns_error() {
197 let mut arr: NeoArray<u32> = NeoArray::new();
198 for i in 0..MAX_SIZE {
199 arr.try_push(i as u32).expect("fits within MAX_SIZE");
200 }
201 assert_eq!(arr.len(), MAX_SIZE);
202 assert_eq!(arr.remaining_capacity(), 0);
203 let err = arr.try_push(MAX_SIZE as u32).unwrap_err();
205 assert_eq!(err.current_len, MAX_SIZE);
206 assert_eq!(
207 err.to_string(),
208 "NeoArray is full (current_len = 1024; MAX_SIZE = 1024)"
209 );
210 }
211}