Skip to main content

platform_data/
point.rs

1/// A structure representing a single value repeated multiple times.
2///
3/// This is useful for creating queries or representing repeated elements
4/// without allocating a vector.
5pub struct Point<T> {
6    index: T,
7    size: usize,
8}
9
10impl<T: PartialEq> Point<T> {
11    pub const fn new(index: T, size: usize) -> Self {
12        Self { index, size }
13    }
14
15    pub const fn is_empty(&self) -> bool {
16        self.len() == 0
17    }
18
19    pub const fn len(&self) -> usize {
20        self.size
21    }
22
23    pub fn is_full(link: &[T]) -> bool {
24        assert!(
25            link.len() >= 2,
26            "cannot determine link's pointless using only its identifier"
27        );
28
29        // SAFETY: slice size is at least 2
30        let a = unsafe { link.first().unwrap_unchecked() };
31        link.iter().skip(1).all(|b| b == a)
32    }
33
34    pub fn is_partial(link: &[T]) -> bool {
35        assert!(
36            link.len() >= 2,
37            "cannot determine link's pointless using only its identifier"
38        );
39
40        // SAFETY: slice size is at least 2
41        let a = unsafe { link.first().unwrap_unchecked() };
42        link.iter().skip(1).any(|b| b == a)
43    }
44
45    pub const fn get(&self, index: usize) -> Option<&T> {
46        if index < self.len() {
47            Some(&self.index)
48        } else {
49            None
50        }
51    }
52}
53
54/// Iterator for Point that yields copies of the stored value.
55pub struct PointIter<T> {
56    value: T,
57    remaining: usize,
58}
59
60impl<T: Copy> Iterator for PointIter<T> {
61    type Item = T;
62
63    fn next(&mut self) -> Option<Self::Item> {
64        if self.remaining > 0 {
65            self.remaining -= 1;
66            Some(self.value)
67        } else {
68            None
69        }
70    }
71
72    fn size_hint(&self) -> (usize, Option<usize>) {
73        (self.remaining, Some(self.remaining))
74    }
75}
76
77impl<T: Copy> ExactSizeIterator for PointIter<T> {}
78
79impl<T: PartialEq + Copy> IntoIterator for Point<T> {
80    type Item = T;
81    type IntoIter = PointIter<T>;
82
83    fn into_iter(self) -> Self::IntoIter {
84        PointIter {
85            value: self.index,
86            remaining: self.size,
87        }
88    }
89}