vrl/value/kind/collection/
index.rs1use crate::path::OwnedSegment;
2use crate::value::kind::Collection;
3use crate::value::kind::collection::{CollectionKey, CollectionRemove};
4
5#[derive(Debug, Clone, Default, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
7pub struct Index(usize);
8
9impl std::fmt::Display for Index {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 self.0.fmt(f)
12 }
13}
14
15impl Index {
16 #[must_use]
18 pub const fn to_usize(self) -> usize {
19 self.0
20 }
21}
22
23impl CollectionKey for Index {
24 fn to_segment(&self) -> OwnedSegment {
25 OwnedSegment::Index(self.0 as isize)
26 }
27}
28
29impl Collection<Index> {
30 #[must_use]
32 pub fn largest_known_index(&self) -> Option<usize> {
33 self.known()
34 .iter()
35 .filter_map(|(i, kind)| {
36 if kind.contains_any_defined() {
37 Some(i.to_usize())
38 } else {
39 None
40 }
41 })
42 .max()
43 }
44
45 #[must_use]
47 pub fn get_positive_index(&self, index: isize) -> Option<usize> {
48 if self.unknown_kind().contains_any_defined() {
49 return None;
51 }
52
53 let negative_index = (-index) as usize;
54 if let Some(largest_known_index) = self.largest_known_index()
55 && largest_known_index >= negative_index - 1
56 {
57 return Some(((largest_known_index as isize) + 1 + index) as usize);
59 }
60 None
62 }
63
64 #[must_use]
66 pub fn min_length(&self) -> usize {
67 self.largest_known_index().map_or(0, |i| i + 1)
68 }
69
70 #[must_use]
72 pub fn exact_length(&self) -> Option<usize> {
73 if self.unknown_kind().contains_any_defined() {
74 None
75 } else {
76 Some(self.min_length())
78 }
79 }
80
81 pub fn remove_shift(&mut self, index: usize) {
84 let min_length = self.min_length();
85 self.known_mut().remove(&index.into());
86 for _ in index..min_length {
87 if let Some(value) = self.known_mut().remove(&(index + 1).into()) {
88 self.known_mut().insert(index.into(), value);
89 }
90 }
91 }
92}
93
94impl CollectionRemove for Collection<Index> {
95 type Key = Index;
96
97 fn remove_known(&mut self, key: &Index) {
98 self.remove_shift(key.0);
99 }
100}
101
102impl From<usize> for Index {
103 fn from(index: usize) -> Self {
104 (&index).into()
105 }
106}
107
108impl From<&usize> for Index {
109 fn from(index: &usize) -> Self {
110 Self(*index)
111 }
112}
113
114impl From<Index> for usize {
115 fn from(index: Index) -> Self {
116 (&index).into()
117 }
118}
119
120impl From<&Index> for usize {
121 fn from(index: &Index) -> Self {
122 index.0
123 }
124}
125
126impl<T: Into<Self>> std::ops::Add<T> for Index {
127 type Output = Self;
128
129 fn add(self, other: T) -> Self {
130 Self(self.0 + other.into().0)
131 }
132}
133
134impl<T: Into<Self>> std::ops::Sub<T> for Index {
135 type Output = Self;
136
137 fn sub(self, other: T) -> Self {
138 Self(self.0 - other.into().0)
139 }
140}