ddshow_types/
operator_addr.rs1use crate::ids::{OperatorId, PortId};
4use core::{
5 convert::TryFrom,
6 fmt::{self, Debug, Display},
7 iter::{FromIterator, IntoIterator},
8 mem::ManuallyDrop,
9 ops::Deref,
10 slice,
11};
12use tinyvec::{ArrayVec, TinyVec};
13
14#[cfg(feature = "enable_abomonation")]
15use abomonation::Abomonation;
16#[cfg(feature = "enable_abomonation")]
17use std::io;
18
19#[cfg(feature = "serde")]
20use serde_dep::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
21
22#[cfg(feature = "rkyv")]
23use rkyv_dep::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
24
25#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
27#[cfg_attr(
28 feature = "serde",
29 derive(SerdeSerialize, SerdeDeserialize),
30 serde(crate = "serde_dep", transparent)
31)]
32#[cfg_attr(
33 feature = "rkyv",
34 derive(Archive, RkyvSerialize, RkyvDeserialize),
35 archive(crate = "rkyv_dep", repr(transparent)),
36 archive_attr(derive(bytecheck::CheckBytes))
37)]
38#[repr(transparent)]
39pub struct OperatorAddr {
40 addr: TinyVec<[OperatorId; 8]>,
41}
42
43impl OperatorAddr {
44 #[inline]
45 pub const fn new(addr: TinyVec<[OperatorId; 8]>) -> Self {
46 Self { addr }
47 }
48
49 #[inline]
50 pub fn from_elem(segment: OperatorId) -> Self {
51 let zero = OperatorId::new(0);
52
53 Self::new(TinyVec::Inline(ArrayVec::from_array_len(
54 [segment, zero, zero, zero, zero, zero, zero, zero],
55 1,
56 )))
57 }
58
59 #[inline]
60 fn from_vec(addr: Vec<OperatorId>) -> Self {
61 let tiny_vec = ArrayVec::try_from(addr.as_slice())
62 .map_or_else(|_| TinyVec::Heap(addr), TinyVec::Inline);
63
64 Self::new(tiny_vec)
65 }
66
67 #[inline]
68 pub fn from_slice(addr: &[OperatorId]) -> Self {
69 let tiny_vec =
70 ArrayVec::try_from(addr).map_or_else(|_| TinyVec::Heap(addr.to_vec()), TinyVec::Inline);
71
72 Self::new(tiny_vec)
73 }
74
75 #[inline]
76 pub fn is_top_level(&self) -> bool {
77 self.len() == 1
78 }
79
80 #[inline]
81 pub fn push(&mut self, segment: PortId) {
82 self.addr.push(OperatorId::new(segment.into_inner()));
83 }
84
85 #[inline]
86 pub fn push_imm(&self, elem: PortId) -> Self {
87 let mut this = self.clone();
88 this.push(elem);
89 this
90 }
91
92 #[inline]
93 pub fn pop(&mut self) -> Option<OperatorId> {
94 self.addr.pop()
95 }
96
97 #[inline]
98 pub fn pop_imm(&self) -> (Self, Option<OperatorId>) {
99 let mut this = self.clone();
100 let popped = this.pop();
101
102 (this, popped)
103 }
104
105 #[inline]
106 pub fn as_slice(&self) -> &[OperatorId] {
107 self.addr.as_slice()
108 }
109
110 #[inline]
111 pub fn iter(&self) -> slice::Iter<'_, OperatorId> {
112 self.as_slice().iter()
113 }
114}
115
116impl From<&[OperatorId]> for OperatorAddr {
117 #[inline]
118 fn from(addr: &[OperatorId]) -> Self {
119 Self::from_slice(addr)
120 }
121}
122
123impl From<&Vec<OperatorId>> for OperatorAddr {
124 #[inline]
125 fn from(addr: &Vec<OperatorId>) -> Self {
126 Self::from_slice(addr)
127 }
128}
129
130impl From<Vec<OperatorId>> for OperatorAddr {
131 #[inline]
132 fn from(addr: Vec<OperatorId>) -> Self {
133 Self::from_vec(addr)
134 }
135}
136
137impl From<Vec<usize>> for OperatorAddr {
138 #[inline]
139 fn from(addr: Vec<usize>) -> Self {
140 let addr: Vec<OperatorId> = {
143 let mut addr = ManuallyDrop::new(addr);
144 let (ptr, len, cap) = (addr.as_mut_ptr().cast(), addr.len(), addr.capacity());
145
146 unsafe { Vec::from_raw_parts(ptr, len, cap) }
148 };
149
150 let tiny_vec = ArrayVec::try_from(addr.as_slice())
151 .map_or_else(|_| TinyVec::Heap(addr), TinyVec::Inline);
152
153 Self::new(tiny_vec)
154 }
155}
156
157impl Deref for OperatorAddr {
158 type Target = [OperatorId];
159
160 #[inline]
161 fn deref(&self) -> &Self::Target {
162 &self.addr
163 }
164}
165
166impl Extend<OperatorId> for OperatorAddr {
167 #[inline]
168 fn extend<T>(&mut self, segments: T)
169 where
170 T: IntoIterator<Item = OperatorId>,
171 {
172 self.addr.extend(segments);
173 }
174}
175
176impl<'a> Extend<&'a OperatorId> for OperatorAddr {
177 #[inline]
178 fn extend<T>(&mut self, segments: T)
179 where
180 T: IntoIterator<Item = &'a OperatorId>,
181 {
182 self.addr.extend(segments.into_iter().copied());
183 }
184}
185
186impl FromIterator<OperatorId> for OperatorAddr {
187 #[inline]
188 fn from_iter<T: IntoIterator<Item = OperatorId>>(iter: T) -> Self {
189 Self {
190 addr: <TinyVec<[OperatorId; 8]>>::from_iter(iter),
191 }
192 }
193}
194
195impl<'a> FromIterator<&'a OperatorId> for OperatorAddr {
196 #[inline]
197 fn from_iter<T: IntoIterator<Item = &'a OperatorId>>(iter: T) -> Self {
198 Self {
199 addr: iter.into_iter().copied().collect(),
200 }
201 }
202}
203
204impl Debug for OperatorAddr {
205 #[inline]
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 Display::fmt(self, f)
209 }
210}
211
212impl Display for OperatorAddr {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 f.debug_list()
215 .entries(self.as_slice().iter().copied().map(OperatorId::into_inner))
218 .finish()
219 }
220}
221
222#[cfg(feature = "enable_abomonation")]
223impl Abomonation for OperatorAddr {
224 #[inline]
225 unsafe fn entomb<W: io::Write>(&self, write: &mut W) -> io::Result<()> {
226 match &self.addr {
227 TinyVec::Inline(array) => array.into_inner().entomb(write),
228 TinyVec::Heap(vec) => vec.entomb(write),
229 }
230 }
231
232 #[inline]
233 unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
234 let mut inner = Vec::new();
235 let output = Vec::exhume(&mut inner, bytes)?;
236 self.addr = TinyVec::Heap(inner);
237
238 Some(output)
239 }
240
241 #[inline]
242 fn extent(&self) -> usize {
243 match &self.addr {
244 TinyVec::Inline(array) => array.into_inner().extent(),
245 TinyVec::Heap(vec) => vec.extent(),
246 }
247 }
248}