h3ron/collections/
indexvec.rs1use crate::{Error, FromH3Index, Index};
2use h3ron_h3_sys::H3Index;
3use std::marker::PhantomData;
4
5#[derive(Debug)]
15pub struct IndexVec<T: FromH3Index + Index> {
16 inner_vec: Vec<H3Index>,
17 phantom: PhantomData<T>,
18}
19
20const EMPTY_H3INDEX: H3Index = 0;
21
22impl<T: FromH3Index + Index> Default for IndexVec<T> {
23 fn default() -> Self {
24 Self {
25 inner_vec: vec![EMPTY_H3INDEX; 0],
26 phantom: Default::default(),
27 }
28 }
29}
30
31impl<T: FromH3Index + Index> IndexVec<T> {
32 pub fn new() -> Self {
33 Default::default()
34 }
35
36 pub fn with_length(length: usize) -> Self {
37 Self {
38 inner_vec: vec![EMPTY_H3INDEX; length],
39 phantom: PhantomData,
40 }
41 }
42
43 pub fn capacity(&self) -> usize {
46 self.inner_vec.capacity()
47 }
48
49 pub fn clear(&mut self) {
50 unsafe {
51 std::ptr::write_bytes(self.inner_vec.as_mut_ptr(), 0, self.inner_vec.len());
52 }
53 }
54
55 pub fn as_slice(&self) -> &[H3Index] {
56 &self.inner_vec
57 }
58
59 pub fn as_mut_slice(&mut self) -> &mut [H3Index] {
60 &mut self.inner_vec
61 }
62
63 pub fn as_ptr(&self) -> *const H3Index {
64 self.inner_vec.as_ptr()
65 }
66
67 pub fn as_mut_ptr(&mut self) -> *mut H3Index {
68 self.inner_vec.as_mut_ptr()
69 }
70
71 pub fn iter(&self) -> UncheckedIter<'_, T> {
72 self.iter_unchecked()
73 }
74
75 pub fn iter_checked(&self) -> CheckedIter<'_, T> {
76 CheckedIter {
77 inner_iter: self.inner_vec.iter(),
78 phantom: Default::default(),
79 }
80 }
81
82 pub fn iter_unchecked(&self) -> UncheckedIter<'_, T> {
83 UncheckedIter {
84 inner_iter: self.inner_vec.iter(),
85 phantom: Default::default(),
86 }
87 }
88
89 pub fn first(&self) -> Option<T> {
90 self.iter_unchecked().next()
91 }
92
93 pub fn is_empty(&self) -> bool {
94 self.first().is_none()
95 }
96
97 pub fn pop(&mut self) -> Option<T> {
98 while let Some(h3index) = self.inner_vec.pop() {
99 if h3index == EMPTY_H3INDEX {
100 continue;
101 }
102 return Some(T::from_h3index(h3index));
103 }
104 None
105 }
106
107 pub fn shrink_to_fit(&mut self) {
108 self.inner_vec.retain(|h3index| *h3index != EMPTY_H3INDEX);
110
111 self.inner_vec.shrink_to_fit();
112 }
113
114 pub fn drain(&mut self) -> UncheckedDrain<'_, T> {
115 UncheckedDrain {
116 inner_drain: self.inner_vec.drain(..),
117 phantom: Default::default(),
118 }
119 }
120
121 pub fn append(&mut self, other: &mut Self) {
122 self.inner_vec.append(&mut other.inner_vec);
123 }
124
125 pub fn dedup(&mut self) {
126 self.inner_vec.dedup();
127 }
128
129 pub fn sort_unstable(&mut self) {
130 self.inner_vec.sort_unstable();
131 }
132
133 pub fn count(&self) -> usize {
134 self.iter_unchecked().count()
135 }
136
137 pub fn push(&mut self, item: T) {
138 self.inner_vec.push(item.h3index());
139 }
140}
141
142impl<'a, T: FromH3Index + Index> IntoIterator for &'a IndexVec<T> {
143 type Item = T;
144 type IntoIter = UncheckedIter<'a, T>;
145
146 fn into_iter(self) -> Self::IntoIter {
147 self.iter_unchecked()
148 }
149}
150
151pub struct CheckedIter<'a, T: FromH3Index + Index> {
152 inner_iter: std::slice::Iter<'a, H3Index>,
153 phantom: PhantomData<T>,
154}
155
156impl<'a, T: FromH3Index + Index> Iterator for CheckedIter<'a, T> {
157 type Item = Result<T, Error>;
158
159 fn next(&mut self) -> Option<Self::Item> {
160 for h3index in &mut self.inner_iter {
161 if *h3index == EMPTY_H3INDEX {
162 continue;
163 }
164 let value = T::from_h3index(*h3index);
165 return match value.validate() {
166 Ok(_) => Some(Ok(value)),
167 Err(e) => Some(Err(e)),
168 };
169 }
170 None
171 }
172
173 fn size_hint(&self) -> (usize, Option<usize>) {
174 self.inner_iter.size_hint()
175 }
176}
177
178pub struct UncheckedIter<'a, T: FromH3Index + Index> {
179 inner_iter: std::slice::Iter<'a, H3Index>,
180 phantom: PhantomData<T>,
181}
182
183impl<'a, T: FromH3Index + Index> Iterator for UncheckedIter<'a, T> {
184 type Item = T;
185
186 fn next(&mut self) -> Option<Self::Item> {
187 for h3index in &mut self.inner_iter {
188 if *h3index == EMPTY_H3INDEX {
189 continue;
190 }
191 return Some(T::from_h3index(*h3index));
192 }
193 None
194 }
195
196 fn size_hint(&self) -> (usize, Option<usize>) {
197 self.inner_iter.size_hint()
198 }
199}
200
201pub struct UncheckedDrain<'a, T: FromH3Index + Index> {
202 inner_drain: std::vec::Drain<'a, H3Index>,
203 phantom: PhantomData<T>,
204}
205
206impl<'a, T: FromH3Index + Index> Iterator for UncheckedDrain<'a, T> {
207 type Item = T;
208
209 fn next(&mut self) -> Option<Self::Item> {
210 for h3index in &mut self.inner_drain {
211 if h3index == EMPTY_H3INDEX {
212 continue;
213 }
214 return Some(Self::Item::from_h3index(h3index));
215 }
216 None
217 }
218
219 fn size_hint(&self) -> (usize, Option<usize>) {
220 self.inner_drain.size_hint()
221 }
222}
223
224impl<T: FromH3Index + Index> From<IndexVec<T>> for Vec<T> {
225 fn from(mut index_vec: IndexVec<T>) -> Self {
226 index_vec.drain().collect()
227 }
228}
229
230impl<T: FromH3Index + Index> TryFrom<Vec<H3Index>> for IndexVec<T> {
231 type Error = Error;
232
233 fn try_from(h3index_vec: Vec<H3Index>) -> Result<Self, Self::Error> {
234 for h3index in &h3index_vec {
235 let value = T::from_h3index(*h3index);
236 value.validate()?;
237 }
238 Ok(Self {
239 inner_vec: h3index_vec,
240 phantom: Default::default(),
241 })
242 }
243}