1use crate::PackedItem;
8use std::borrow::Cow;
9use std::iter::{Extend, FromIterator};
10use std::ops::Index;
11
12pub struct PackedVec<T: ?Sized + PackedItem> {
18 data: Vec<u8>,
19 offsets: Vec<usize>,
23 _phantom: std::marker::PhantomData<fn() -> T>,
32}
33
34impl<T: ?Sized + PackedItem> PackedVec<T> {
35 pub fn new() -> Self {
37 Self { data: Vec::new(), offsets: Vec::new(), _phantom: std::marker::PhantomData }
38 }
39
40 pub fn with_capacity(element_capacity: usize, buffer_capacity: usize) -> Self {
47 Self {
48 data: Vec::with_capacity(buffer_capacity),
49 offsets: Vec::with_capacity(element_capacity),
50 _phantom: std::marker::PhantomData,
51 }
52 }
53
54 pub fn clear(&mut self) {
56 self.data.clear();
57 self.offsets.clear();
58 }
59
60 pub fn from_slice<U: AsRef<T>>(slices: &[U]) -> Self {
63 let element_capacity = slices.len();
64 let buffer_capacity = slices.iter().map(|s| s.as_ref().as_bytes().len()).sum();
65 let mut vec = Self::with_capacity(element_capacity, buffer_capacity);
66 vec.extend(slices);
67 vec
68 }
69
70 pub fn reserve(&mut self, additional: usize) {
72 self.offsets.reserve(additional);
73 }
74
75 pub fn shrink_to_fit(&mut self) {
77 self.data.shrink_to_fit();
78 self.offsets.shrink_to_fit();
79 }
80
81 pub fn push(&mut self, slice: &T) {
83 self.data.extend_from_slice(slice.as_bytes());
84 self.offsets.push(self.data.len());
85 }
86
87 pub fn get(&self, index: usize) -> Option<&T> {
89 if index >= self.len() {
90 return None;
91 }
92 Some(unsafe { self.get_unchecked(index) })
94 }
95
96 pub unsafe fn get_unchecked(&self, index: usize) -> &T {
102 let start = if index == 0 {
103 0
104 } else {
105 unsafe { *self.offsets.get_unchecked(index - 1) }
107 };
108
109 let end = unsafe { *self.offsets.get_unchecked(index) };
112
113 let bytes = unsafe { self.data.get_unchecked(start..end) };
116
117 unsafe { T::from_bytes(bytes) }
122 }
123
124 pub fn len(&self) -> usize {
126 self.offsets.len()
127 }
128
129 pub fn buffer_len(&self) -> usize {
131 self.data.len()
132 }
133
134 pub fn is_empty(&self) -> bool {
136 self.offsets.is_empty()
137 }
138
139 pub fn binary_search(&self, x: &T) -> Result<usize, usize>
149 where
150 T: Ord,
151 {
152 self.binary_search_by(|p| p.cmp(x))
153 }
154
155 pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
165 where
166 F: FnMut(&'a T) -> std::cmp::Ordering,
167 {
168 self.offsets.binary_search_by(|end| {
181 let end_ptr = end as *const usize;
184 let index = unsafe { end_ptr.offset_from_unsigned(self.offsets.as_ptr()) };
185
186 let slice = unsafe { self.get_unchecked(index) };
188 f(slice)
189 })
190 }
191
192 pub fn first(&self) -> Option<&T> {
194 self.get(0)
195 }
196
197 pub fn last(&self) -> Option<&T> {
199 let len = self.len();
200 if len == 0 {
201 None
202 } else {
203 Some(unsafe { self.get_unchecked(len - 1) })
205 }
206 }
207
208 pub fn iter(&self) -> Iter<'_, T> {
210 Iter { vec: self, range: 0..self.len() }
211 }
212
213 pub fn drain(&mut self) -> Drain<'_, T> {
215 let len = self.len();
216 Drain { vec: self, cursor: 0, len }
217 }
218
219 pub fn range<R: std::ops::RangeBounds<usize>>(&self, range: R) -> Iter<'_, T> {
224 let range = crate::compute_range_indices(self.len(), range, |&idx| Ok(idx));
225 Iter { vec: self, range }
226 }
227}
228
229impl<T: ?Sized + PackedItem> Default for PackedVec<T> {
230 fn default() -> Self {
231 Self::new()
232 }
233}
234
235impl<T: ?Sized + PackedItem> Clone for PackedVec<T> {
236 fn clone(&self) -> Self {
237 Self {
238 data: self.data.clone(),
239 offsets: self.offsets.clone(),
240 _phantom: std::marker::PhantomData,
241 }
242 }
243}
244
245impl<T: ?Sized + PackedItem> PartialEq for PackedVec<T> {
246 fn eq(&self, other: &Self) -> bool {
247 self.data == other.data && self.offsets == other.offsets
248 }
249}
250
251impl<T: ?Sized + PackedItem> Eq for PackedVec<T> {}
252
253impl<T: ?Sized + PackedItem> std::hash::Hash for PackedVec<T> {
254 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
255 self.data.hash(state);
256 self.offsets.hash(state);
257 }
258}
259
260impl<T: ?Sized + PackedItem> std::fmt::Debug for PackedVec<T>
261where
262 T: std::fmt::Debug,
263{
264 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
265 f.debug_list().entries::<&T, _>(self.iter()).finish()
266 }
267}
268
269impl<'a, T: ?Sized + PackedItem> IntoIterator for &'a PackedVec<T> {
270 type Item = &'a T;
271 type IntoIter = Iter<'a, T>;
272
273 fn into_iter(self) -> Self::IntoIter {
274 Iter::<T> { vec: self, range: 0..self.len() }
275 }
276}
277
278pub struct Iter<'a, T: ?Sized + PackedItem> {
280 vec: &'a PackedVec<T>,
281 range: std::ops::Range<usize>,
282}
283
284impl<'a, T: ?Sized + PackedItem> Iterator for Iter<'a, T> {
285 type Item = &'a T;
286
287 fn next(&mut self) -> Option<Self::Item> {
288 let i = self.range.next()?;
289 self.vec.get(i)
290 }
291
292 fn size_hint(&self) -> (usize, Option<usize>) {
293 self.range.size_hint()
294 }
295}
296
297impl<'a, T: ?Sized + PackedItem> DoubleEndedIterator for Iter<'a, T> {
298 fn next_back(&mut self) -> Option<Self::Item> {
299 let i = self.range.next_back()?;
300 self.vec.get(i)
301 }
302}
303
304impl<'a, T: ?Sized + PackedItem> ExactSizeIterator for Iter<'a, T> {}
305
306pub struct Drain<'a, T: ?Sized + PackedItem> {
308 vec: &'a mut PackedVec<T>,
309 cursor: usize,
310 len: usize,
311}
312
313impl<'a, T: ?Sized + PackedItem> Drain<'a, T> {
314 pub fn next(&mut self) -> Option<&T> {
316 if self.cursor >= self.len {
317 return None;
318 }
319 let i = self.cursor;
320 self.cursor += 1;
321 self.vec.get(i)
322 }
323
324 pub fn next_back(&mut self) -> Option<&T> {
326 if self.cursor >= self.len {
327 return None;
328 }
329 self.len -= 1;
330 self.vec.get(self.len)
331 }
332
333 pub fn len(&self) -> usize {
335 self.len - self.cursor
336 }
337}
338
339impl<'a, T: ?Sized + PackedItem> Drop for Drain<'a, T> {
340 fn drop(&mut self) {
341 self.vec.clear();
342 }
343}
344
345impl<T: ?Sized + PackedItem> Index<usize> for PackedVec<T> {
346 type Output = T;
347
348 fn index(&self, index: usize) -> &Self::Output {
349 self.get(index).expect("index out of bounds")
350 }
351}
352
353impl<U: AsRef<T>, T: ?Sized + PackedItem> Extend<U> for PackedVec<T> {
354 fn extend<I: IntoIterator<Item = U>>(&mut self, iter: I) {
355 let iter = iter.into_iter();
356 let (lower, _) = iter.size_hint();
357 self.offsets.reserve(lower);
358 for item in iter {
359 self.push(item.as_ref());
360 }
361 }
362}
363
364impl<U: AsRef<T>, T: ?Sized + PackedItem> FromIterator<U> for PackedVec<T> {
365 fn from_iter<I: IntoIterator<Item = U>>(iter: I) -> Self {
366 let iter = iter.into_iter();
367 let (lower, _) = iter.size_hint();
368 let mut vec = Self::with_capacity(lower, 0);
369 vec.extend(iter);
370 vec
371 }
372}
373
374impl<U, T: ?Sized + PackedItem, const N: usize> From<[U; N]> for PackedVec<T>
375where
376 U: AsRef<T>,
377{
378 fn from(arr: [U; N]) -> Self {
379 Self::from_iter(arr)
380 }
381}
382
383impl<T: ?Sized + PackedItem> serde::Serialize for PackedVec<T>
384where
385 T: serde::Serialize,
386{
387 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
388 use serde::ser::SerializeSeq;
389 let mut seq = serializer.serialize_seq(Some(self.len()))?;
390 for item in self.iter() {
391 seq.serialize_element(item)?;
392 }
393 seq.end()
394 }
395}
396
397impl<'de, T: ?Sized + PackedItem + 'de> serde::Deserialize<'de> for PackedVec<T>
398where
399 T: ToOwned,
400 Cow<'de, T>: serde::Deserialize<'de>,
401{
402 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
403 struct SeqVisitor<T: ?Sized + PackedItem>(std::marker::PhantomData<fn() -> T>);
404
405 impl<'de, T: ?Sized + PackedItem + 'de> serde::de::Visitor<'de> for SeqVisitor<T>
406 where
407 T: ToOwned,
408 Cow<'de, T>: serde::Deserialize<'de>,
409 {
410 type Value = PackedVec<T>;
411
412 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
413 formatter.write_str("a sequence of items")
414 }
415
416 fn visit_seq<A: serde::de::SeqAccess<'de>>(
417 self,
418 mut seq: A,
419 ) -> Result<Self::Value, A::Error> {
420 let mut vec = PackedVec::with_capacity(seq.size_hint().unwrap_or(0), 0);
421 while let Some(elem) = seq.next_element::<Cow<'de, T>>()? {
422 vec.push(elem.as_ref());
423 }
424 Ok(vec)
425 }
426 }
427
428 deserializer.deserialize_seq(SeqVisitor(std::marker::PhantomData))
429 }
430}
431
432#[cfg(test)]
433mod tests {
434 use super::*;
435
436 #[test]
437 fn test_with_capacity() {
438 let pv: PackedVec<[u8]> = PackedVec::with_capacity(10, 20);
439 assert!(pv.offsets.capacity() >= 10);
440 assert!(pv.data.capacity() >= 20);
441 assert_eq!(pv.len(), 0);
442 }
443
444 #[test]
445 fn test_from_slice() {
446 let slices: &[&[u8]] = &[&[1, 2], &[3], &[4, 5, 6]];
447 let pv = PackedVec::from_slice(slices);
448 assert_eq!(pv.len(), 3);
449 assert_eq!(pv.get(0), Some(&[1, 2][..]));
450 assert_eq!(pv.get(1), Some(&[3][..]));
451 assert_eq!(pv.get(2), Some(&[4, 5, 6][..]));
452 assert!(pv.offsets.capacity() >= 3);
453 assert!(pv.data.capacity() >= 6);
454 }
455
456 #[test]
457 fn test_packed_vec() {
458 let mut pv: PackedVec<[u8]> = PackedVec::new();
459 pv.push(&[1u8, 2][..]);
460 pv.push(&[][..]);
461 pv.push(&[3, 4, 5][..]);
462
463 assert_eq!(pv.len(), 3);
464 assert!(!pv.is_empty());
465
466 assert_eq!(pv.get(0), Some(&[1u8, 2][..]));
467 assert_eq!(pv.get(1), Some(&[] as &[u8]));
468 assert_eq!(pv.get(2), Some(&[3u8, 4, 5][..]));
469 assert_eq!(pv.get(3), None);
470
471 assert_eq!(pv.get(0).unwrap(), &[1u8, 2][..]);
472 assert_eq!(pv.get(1).unwrap(), &[] as &[u8]);
473
474 let collected: Vec<_> = pv.iter().collect();
475 assert_eq!(collected, vec![&[1u8, 2][..], &[] as &[u8], &[3u8, 4, 5][..]]);
476 }
477
478 #[test]
479 fn test_first_last() {
480 let mut pv: PackedVec<[u8]> = PackedVec::new();
481 assert_eq!(pv.first(), None);
482 assert_eq!(pv.last(), None);
483
484 pv.push(&[1][..]);
485 assert_eq!(pv.first(), Some(&[1][..]));
486 assert_eq!(pv.last(), Some(&[1][..]));
487
488 pv.push(&[2, 3][..]);
489 assert_eq!(pv.first(), Some(&[1][..]));
490 assert_eq!(pv.last(), Some(&[2, 3][..]));
491 }
492
493 #[test]
494 fn test_extend_from_iterator() {
495 let pv: PackedVec<[u8]> = vec![vec![1], vec![2, 3]].iter().map(|v| v.as_slice()).collect();
496 assert_eq!(pv.len(), 2);
497 let slice: &[u8] = pv.get(1).unwrap();
498 assert_eq!(slice, &[2, 3][..]);
499 }
500
501 #[test]
502 fn test_drain() {
503 let mut pv: PackedVec<[u8]> = PackedVec::new();
504 pv.push(&[1][..]);
505 pv.push(&[2, 3][..]);
506 pv.push(&[4, 5, 6][..]);
507
508 let mut drain = pv.drain();
509 assert_eq!(drain.len(), 3);
510
511 assert_eq!(drain.next(), Some(&[1][..]));
513 assert_eq!(drain.len(), 2);
514
515 assert_eq!(drain.next_back(), Some(&[4, 5, 6][..]));
517 assert_eq!(drain.len(), 1);
518
519 assert_eq!(drain.next(), Some(&[2, 3][..]));
521 assert_eq!(drain.len(), 0);
522
523 assert_eq!(drain.next(), None);
525 assert_eq!(drain.next_back(), None);
526 }
527
528 #[test]
529 fn test_drain_drop_clears() {
530 let mut pv: PackedVec<[u8]> = PackedVec::new();
531 pv.push(&[1][..]);
532 pv.push(&[2, 3][..]);
533
534 {
535 let mut drain = pv.drain();
536 assert_eq!(drain.next(), Some(&[1][..]));
537 }
539
540 assert!(pv.is_empty());
541 assert_eq!(pv.len(), 0);
542
543 assert!(pv.offsets.is_empty());
545 assert!(pv.data.is_empty());
546 }
547
548 #[test]
549 fn test_binary_search_empty() {
550 let pv: PackedVec<[u8]> = PackedVec::new();
551 assert_eq!(pv.binary_search_by(|x| x.cmp(&[1u8][..])), Err(0));
552 }
553
554 #[test]
555 fn test_binary_search() {
556 let mut pv: PackedVec<[u8]> = PackedVec::new();
557 pv.push(&[1]);
558 pv.push(&[3]);
559 pv.push(&[5]);
560
561 assert_eq!(pv.binary_search_by(|x| x.cmp(&[1u8][..])), Ok(0));
562 assert_eq!(pv.binary_search_by(|x| x.cmp(&[3u8][..])), Ok(1));
563 assert_eq!(pv.binary_search_by(|x| x.cmp(&[5u8][..])), Ok(2));
564 assert_eq!(pv.binary_search_by(|x| x.cmp(&[2u8][..])), Err(1));
565 assert_eq!(pv.binary_search_by(|x| x.cmp(&[0u8][..])), Err(0));
566 assert_eq!(pv.binary_search_by(|x| x.cmp(&[6u8][..])), Err(3));
567 }
568
569 #[test]
570 fn test_packed_str_vec() {
571 let mut pv: PackedVec<str> = PackedVec::new();
572 pv.push("hello");
573 pv.push("");
574 pv.push("world!!");
575
576 assert_eq!(pv.len(), 3);
577 assert!(!pv.is_empty());
578
579 assert_eq!(pv.get(0), Some("hello"));
580 assert_eq!(pv.get(1), Some(""));
581 assert_eq!(pv.get(2), Some("world!!"));
582 assert_eq!(pv.get(3), None);
583
584 assert_eq!(pv.get(0).unwrap(), "hello");
585 assert_eq!(pv.get(1).unwrap(), "");
586
587 let collected: Vec<_> = pv.iter().collect();
588 assert_eq!(collected, vec!["hello", "", "world!!"]);
589 }
590
591 #[test]
592 fn test_serde() {
593 let mut pv: PackedVec<str> = PackedVec::new();
594 pv.push("hello");
595 pv.push("world");
596 let serialized = serde_json::to_string(&pv).unwrap();
597 let deserialized: PackedVec<str> = serde_json::from_str(&serialized).unwrap();
598 assert_eq!(pv, deserialized);
599 }
600}