1use super::{
9 handle::{Handle, Index},
10 Arena,
11};
12
13use std::{fmt, marker::PhantomData, ops};
14
15#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
17#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
18#[cfg_attr(
19 any(feature = "serialize", feature = "deserialize"),
20 serde(transparent)
21)]
22#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23#[cfg_attr(test, derive(PartialEq))]
24pub struct Range<T> {
25 pub(super) inner: ops::Range<u32>,
26 #[cfg_attr(any(feature = "serialize", feature = "deserialize"), serde(skip))]
27 marker: PhantomData<T>,
28}
29
30impl<T> Range<T> {
31 pub(crate) const fn erase_type(self) -> Range<()> {
32 let Self { inner, marker: _ } = self;
33 Range {
34 inner,
35 marker: PhantomData,
36 }
37 }
38}
39
40#[derive(Clone, Debug, thiserror::Error)]
42#[cfg_attr(test, derive(PartialEq))]
43#[error("Handle range {range:?} of {kind} is either not present, or inaccessible yet")]
44pub struct BadRangeError {
45 kind: &'static str,
48 range: Range<()>,
49}
50
51impl BadRangeError {
52 pub fn new<T>(range: Range<T>) -> Self {
53 Self {
54 kind: std::any::type_name::<T>(),
55 range: range.erase_type(),
56 }
57 }
58}
59
60impl<T> Clone for Range<T> {
61 fn clone(&self) -> Self {
62 Range {
63 inner: self.inner.clone(),
64 marker: self.marker,
65 }
66 }
67}
68
69impl<T> fmt::Debug for Range<T> {
70 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
71 write!(formatter, "[{}..{}]", self.inner.start, self.inner.end)
72 }
73}
74
75impl<T> Iterator for Range<T> {
76 type Item = Handle<T>;
77 fn next(&mut self) -> Option<Self::Item> {
78 if self.inner.start < self.inner.end {
79 let next = self.inner.start;
80 self.inner.start += 1;
81 Some(Handle::new(Index::new(next).unwrap()))
82 } else {
83 None
84 }
85 }
86}
87
88impl<T> Range<T> {
89 pub fn new_from_bounds(first: Handle<T>, last: Handle<T>) -> Self {
91 Self {
92 inner: (first.index() as u32)..(last.index() as u32 + 1),
93 marker: Default::default(),
94 }
95 }
96
97 pub(super) fn full_range_from_size(size: usize) -> Self {
99 Self {
100 inner: 0..size as u32,
101 marker: Default::default(),
102 }
103 }
104
105 pub fn first_and_last(&self) -> Option<(Handle<T>, Handle<T>)> {
110 if self.inner.start < self.inner.end {
111 Some((
112 Handle::new(Index::new(self.inner.start).unwrap()),
115 Handle::new(Index::new(self.inner.end - 1).unwrap()),
116 ))
117 } else {
118 None
119 }
120 }
121
122 pub fn index_range(&self) -> ops::Range<u32> {
124 self.inner.clone()
125 }
126
127 pub fn from_index_range(inner: ops::Range<u32>, arena: &Arena<T>) -> Self {
129 assert!(inner.start <= inner.end);
133 assert!(inner.end as usize <= arena.len());
134 Self {
135 inner,
136 marker: Default::default(),
137 }
138 }
139}