1use core::ops::{Deref, DerefMut};
5
6use alloc::{boxed::Box, vec::Vec};
7
8use crate::{
9 ConstString,
10 any_port_value::AnyPortValue,
11 bind::{
12 BindCommons,
13 bound_value::{BoundValueReadGuard, BoundValueWriteGuard},
14 },
15 collections::{PortCollection, PortCollectionAccessors, PortCollectionAccessorsCommon, PortCollectionMut},
16 error::Error,
17 port_variant::PortVariant,
18};
19
20#[derive(Clone, Debug, Default)]
22#[repr(transparent)]
23pub struct PortVec(Vec<(ConstString, PortVariant)>);
24
25impl PortVec {
26 pub fn with_capacity(size: usize) -> Self {
27 Self(Vec::with_capacity(size))
28 }
29
30 pub fn from_array<const N: usize>(array: [(ConstString, PortVariant); N]) -> Self {
31 Self(Vec::from(array))
32 }
33
34 pub fn inner(&self) -> &Vec<(ConstString, PortVariant)> {
35 &self.0
36 }
37
38 pub fn inner_mut(&mut self) -> &mut Vec<(ConstString, PortVariant)> {
39 &mut self.0
40 }
41}
42
43impl Deref for PortVec {
44 type Target = Vec<(ConstString, PortVariant)>;
45
46 fn deref(&self) -> &Self::Target {
47 &self.0
48 }
49}
50
51impl DerefMut for PortVec {
52 fn deref_mut(&mut self) -> &mut Self::Target {
53 &mut self.0
54 }
55}
56
57impl PortCollection for PortVec {
58 fn find(&self, name: &str) -> Option<&PortVariant> {
59 self.0
60 .iter()
61 .find(|port| &*port.0 == name)
62 .map(|v| &v.1 as _)
63 }
64
65 fn find_mut(&mut self, name: &str) -> Option<&mut PortVariant> {
66 self.0
67 .iter_mut()
68 .find(|port| &*port.0 == name)
69 .map(|v| &mut v.1 as _)
70 }
71
72 fn set_from_str(&mut self, name: &str, value: &str) -> Result<(), Error> {
73 if let Some(port) = self.find_mut(name) {
74 port.set_from_str(value)
75 } else {
76 Err(Error::NotFound { name: name.into() })
77 }
78 }
79
80 fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (&'a str, &'a PortVariant)> + 'a> {
81 Box::new(self.0.iter().map(|(name, port)| (&**name, port)))
82 }
83
84 fn iter_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = (&'a str, &'a mut PortVariant)> + 'a> {
85 Box::new(
86 self.0
87 .iter_mut()
88 .map(|(name, port)| (&**name, port)),
89 )
90 }
91}
92
93impl PortCollectionMut for PortVec {
94 fn add(&mut self, name: ConstString, port: PortVariant) -> Result<(), Error> {
95 if self.find(&name).is_some() {
96 Err(Error::AlreadyExists)
97 } else {
98 self.0.push((name, port));
99 Ok(())
100 }
101 }
102
103 fn delete(&mut self, name: &str) -> Result<PortVariant, Error> {
104 let name = name.into();
105 if let Some(index) = self.0.iter().position(|r| r.0 == name) {
106 Ok(self.0.remove(index).1)
107 } else {
108 Err(Error::NotFound { name })
109 }
110 }
111}
112
113impl PortCollectionAccessorsCommon for PortVec {
114 fn contains_name(&self, name: &str) -> bool {
115 self.find(name).is_some()
116 }
117
118 fn give_to_bound(&self, name: &str, bound: &mut dyn BindCommons) -> Result<(), Error> {
119 self.find(name)
120 .map_or(Err(Error::NotFound { name: name.into() }), |port| {
121 bound.use_from_variant(port)
122 })
123 }
124
125 fn give_to_collection(
126 &self,
127 name: &str,
128 other_collection: &mut dyn PortCollection,
129 other_name: &str,
130 ) -> Result<(), Error> {
131 self.find(name)
132 .map_or(Err(Error::NotFound { name: name.into() }), |port| {
133 other_collection
134 .find_mut(other_name)
135 .map_or(Err(Error::OtherNotFound { name: other_name.into() }), |variant| {
136 variant.use_from_variant(port)
137 })
138 })
139 }
140
141 fn give_to_variant(&self, name: &str, variant: &mut PortVariant) -> Result<(), Error> {
142 self.find(name)
143 .map_or(Err(Error::NotFound { name: name.into() }), |port| {
144 variant.use_from_variant(port)
145 })
146 }
147
148 fn sequence_number(&self, name: &str) -> Result<u32, Error> {
149 if let Some(port) = self.find(name) {
150 Ok(port.sequence_number())
151 } else {
152 Err(Error::NotFound { name: name.into() })
153 }
154 }
155
156 fn use_from_bound(&mut self, name: &str, bound: &dyn BindCommons) -> Result<(), Error> {
157 self.find_mut(name)
158 .map_or(Err(Error::NotFound { name: name.into() }), |port| port.use_from_bound(bound))
159 }
160
161 fn use_from_collection(
162 &mut self,
163 name: &str,
164 other_collection: &dyn PortCollection,
165 other_name: &str,
166 ) -> Result<(), Error> {
167 other_collection
168 .find(other_name)
169 .map_or(Err(Error::OtherNotFound { name: other_name.into() }), |other| {
170 self.use_from_variant(name, other)
171 })
172 }
173
174 fn use_from_variant(&mut self, name: &str, variant: &PortVariant) -> Result<(), Error> {
175 if let Some(self_port) = self.find_mut(name) {
176 self_port.use_from_variant(variant)
177 } else {
178 Err(Error::NotFound { name: name.into() })
179 }
180 }
181}
182
183impl PortCollectionAccessors for PortVec {
184 fn contains<T: AnyPortValue>(&self, name: &str) -> Result<bool, Error> {
185 if let Some(p) = self.find(name) {
186 if p.is::<T>() { Ok(true) } else { Err(Error::DataType) }
187 } else {
188 Ok(false)
189 }
190 }
191
192 fn get<T>(&self, name: &str) -> Result<T, Error>
193 where
194 T: AnyPortValue + Clone,
195 {
196 if let Some(port) = self.find(name) {
197 match port.get::<T>()? {
198 Some(t) => Ok(t),
199 None => Err(Error::NoValueSet),
200 }
201 } else {
202 Err(Error::NotFound { name: name.into() })
203 }
204 }
205
206 fn read<T: AnyPortValue>(&self, name: &str) -> Result<BoundValueReadGuard<T>, Error> {
207 if let Some(port) = self.find(name) {
208 port.read()
209 } else {
210 Err(Error::NotFound { name: name.into() })
211 }
212 }
213
214 fn try_read<T: AnyPortValue>(&self, name: &str) -> Result<BoundValueReadGuard<T>, Error> {
215 if let Some(port) = self.find(name) {
216 port.try_read()
217 } else {
218 Err(Error::NotFound { name: name.into() })
219 }
220 }
221
222 fn replace<T: AnyPortValue>(&mut self, name: &str, value: T) -> Result<Option<T>, Error> {
223 if let Some(port) = self.find_mut(name) {
224 port.replace(value)
225 } else {
226 Err(Error::NotFound { name: name.into() })
227 }
228 }
229
230 fn set<T: AnyPortValue>(&mut self, name: &str, value: T) -> Result<(), Error> {
231 if let Some(port) = self.find_mut(name) {
232 port.set(value)
233 } else {
234 Err(Error::NotFound { name: name.into() })
235 }
236 }
237
238 fn take<T: AnyPortValue>(&mut self, name: &str) -> Result<Option<T>, Error> {
239 if let Some(port) = self.find_mut(name) {
240 port.take()
241 } else {
242 Err(Error::NotFound { name: name.into() })
243 }
244 }
245
246 fn write<T: AnyPortValue>(&mut self, name: &str) -> Result<BoundValueWriteGuard<T>, Error> {
247 if let Some(port) = self.find_mut(name) {
248 port.write()
249 } else {
250 Err(Error::NotFound { name: name.into() })
251 }
252 }
253
254 fn try_write<T: AnyPortValue>(&mut self, name: &str) -> Result<BoundValueWriteGuard<T>, Error> {
255 if let Some(port) = self.find_mut(name) {
256 port.try_write()
257 } else {
258 Err(Error::NotFound { name: name.into() })
259 }
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use super::*;
266
267 const fn is_normal<T: Sized + Send + Sync>() {}
268
269 #[test]
271 const fn normal_types() {
272 is_normal::<&PortVec>();
273 is_normal::<PortVec>();
274 }
275
276 #[test]
277 fn insert_duplicate_name_returns_already_exists() {
278 let mut vec = PortVec::default();
279 let port = crate::PortVariant::create_outbound(42i32);
280 assert!(vec.add("dup".into(), port).is_ok());
281
282 let port2 = crate::PortVariant::create_inbound(0i32);
283 assert_eq!(vec.add("dup".into(), port2), Err(crate::error::Error::AlreadyExists));
284 }
285
286 #[test]
287 fn set_from_str_existing_port() {
288 let mut vec = PortVec::default();
289 let port = crate::PortVariant::create_outbound_parseable(0i32);
290 vec.add("val".into(), port).unwrap();
291 assert!(vec.set_from_str("val", "42").is_ok());
292 }
293
294 #[test]
295 fn set_from_str_missing_port() {
296 let mut vec = PortVec::default();
297 assert_eq!(
298 vec.set_from_str("missing", "42"),
299 Err(crate::error::Error::NotFound { name: "missing".into() })
300 );
301 }
302
303 #[test]
304 fn iter_empty_yields_nothing() {
305 let vec = PortVec::default();
306 assert_eq!(vec.iter().count(), 0);
307 }
308
309 #[test]
310 fn iter_yields_all_entries_in_insertion_order() {
311 let mut vec = PortVec::default();
312 vec.add("a".into(), crate::PortVariant::create_inbound(1i32))
313 .unwrap();
314 vec.add("b".into(), crate::PortVariant::create_outbound(2i32))
315 .unwrap();
316 vec.add("c".into(), crate::PortVariant::create_inoutbound(3i32))
317 .unwrap();
318
319 let names: Vec<&str> = vec.iter().map(|(n, _)| n).collect();
320 assert_eq!(names, ["a", "b", "c"]);
321 assert_eq!(vec.iter().count(), 3);
322 }
323
324 #[test]
325 fn iter_yields_matching_port_refs() {
326 let mut vec = PortVec::default();
327 vec.add("x".into(), crate::PortVariant::create_inbound(42i32))
328 .unwrap();
329 let (name, port) = vec.iter().next().unwrap();
330 assert_eq!(name, "x");
331 assert_eq!(port.get::<i32>().unwrap(), Some(42));
332 }
333
334 #[test]
335 fn iter_mut_empty_yields_nothing() {
336 let mut vec = PortVec::default();
337 assert_eq!(vec.iter_mut().count(), 0);
338 }
339
340 #[test]
341 fn iter_mut_yields_all_entries_in_insertion_order() {
342 let mut vec = PortVec::default();
343 vec.add("a".into(), crate::PortVariant::create_inbound(1i32))
344 .unwrap();
345 vec.add("b".into(), crate::PortVariant::create_outbound(2i32))
346 .unwrap();
347 vec.add("c".into(), crate::PortVariant::create_inoutbound(3i32))
348 .unwrap();
349
350 let names: Vec<&str> = vec.iter_mut().map(|(n, _)| n).collect();
351 assert_eq!(names, ["a", "b", "c"]);
352 assert_eq!(vec.iter_mut().count(), 3);
353 }
354
355 #[test]
356 fn iter_mut_allows_mutation_of_port_values() {
357 let mut vec = PortVec::default();
358 vec.add("a".into(), crate::PortVariant::create_inoutbound(1i32))
359 .unwrap();
360 vec.add("b".into(), crate::PortVariant::create_inoutbound(2i32))
361 .unwrap();
362 for (_, port) in vec.iter_mut() {
363 let current = port.get::<i32>().unwrap().unwrap();
364 port.set(current * 10).unwrap();
365 }
366 assert_eq!(vec.get::<i32>("a"), Ok(10));
367 assert_eq!(vec.get::<i32>("b"), Ok(20));
368 }
369
370 #[test]
371 fn iter_mut_yields_matching_port_refs() {
372 let mut vec = PortVec::default();
373 vec.add("x".into(), crate::PortVariant::create_inoutbound(42i32))
374 .unwrap();
375 {
376 let (name, port) = vec.iter_mut().next().unwrap();
377 assert_eq!(name, "x");
378 port.set(99i32).unwrap();
379 }
380 assert_eq!(vec.get::<i32>("x"), Ok(99));
381 }
382}