Skip to main content

melodium_common/executive/
transmission.rs

1use super::{Data, PackedArray, Value};
2use std::collections::VecDeque;
3use std::convert::TryInto;
4use std::sync::Arc;
5
6#[derive(Debug, Clone)]
7pub enum TransmissionError {
8    NoReceiver,
9    EverythingClosed,
10    NoData,
11    /// A received value's runtime type didn't match the type it was cast to (see
12    /// `InputExt::recv_one_as`/`recv_many_as`). Replaces what used to be an `.unwrap()`
13    /// panic at call sites doing this cast by hand.
14    TypeMismatch,
15}
16
17pub type SendResult = Result<(), TransmissionError>;
18pub type RecvResult<T> = Result<T, TransmissionError>;
19
20#[derive(Clone, Debug, PartialEq)]
21pub enum TransmissionValue {
22    Void(VecDeque<()>),
23
24    I8(VecDeque<i8>),
25    I16(VecDeque<i16>),
26    I32(VecDeque<i32>),
27    I64(VecDeque<i64>),
28    I128(VecDeque<i128>),
29
30    U8(VecDeque<u8>),
31    U16(VecDeque<u16>),
32    U32(VecDeque<u32>),
33    U64(VecDeque<u64>),
34    U128(VecDeque<u128>),
35
36    F32(VecDeque<f32>),
37    F64(VecDeque<f64>),
38
39    Bool(VecDeque<bool>),
40    Byte(VecDeque<u8>),
41    Char(VecDeque<char>),
42    String(VecDeque<String>),
43
44    // The `Packed*` variants below are the batch-of-ticks counterpart of `Value::Packed`:
45    // each queue entry is one whole packed array (one `Stream<Vec<T>>` tick, or a lone
46    // `Vec<T>` value), not one scalar. They deliberately don't share storage with the
47    // scalar variants above (`I8`, `U8`, ...) even for the same `T` — flattening a
48    // `Stream<Vec<byte>>` into the same buffer as a `Stream<byte>` would destroy the
49    // boundary between ticks (each array can be a different length). See ticket #116.
50    PackedI8(VecDeque<Arc<Vec<i8>>>),
51    PackedI16(VecDeque<Arc<Vec<i16>>>),
52    PackedI32(VecDeque<Arc<Vec<i32>>>),
53    PackedI64(VecDeque<Arc<Vec<i64>>>),
54    PackedI128(VecDeque<Arc<Vec<i128>>>),
55
56    PackedU8(VecDeque<Arc<Vec<u8>>>),
57    PackedU16(VecDeque<Arc<Vec<u16>>>),
58    PackedU32(VecDeque<Arc<Vec<u32>>>),
59    PackedU64(VecDeque<Arc<Vec<u64>>>),
60    PackedU128(VecDeque<Arc<Vec<u128>>>),
61
62    PackedF32(VecDeque<Arc<Vec<f32>>>),
63    PackedF64(VecDeque<Arc<Vec<f64>>>),
64
65    PackedBool(VecDeque<Arc<Vec<bool>>>),
66    PackedByte(VecDeque<Arc<Vec<u8>>>),
67    PackedChar(VecDeque<Arc<Vec<char>>>),
68
69    /// This variant handle all non-optimized cases.
70    ///
71    /// Optimized (and non-optimized) cases are at the implementation discretion.
72    Other(VecDeque<Value>),
73}
74
75impl TransmissionValue {
76    pub fn new(value: Value) -> Self {
77        match value {
78            Value::Void(value) => TransmissionValue::Void({
79                let mut vec = VecDeque::new();
80                vec.push_back(value);
81                vec
82            }),
83            Value::I8(value) => TransmissionValue::I8({
84                let mut vec = VecDeque::new();
85                vec.push_back(value);
86                vec
87            }),
88            Value::I16(value) => TransmissionValue::I16({
89                let mut vec = VecDeque::new();
90                vec.push_back(value);
91                vec
92            }),
93            Value::I32(value) => TransmissionValue::I32({
94                let mut vec = VecDeque::new();
95                vec.push_back(value);
96                vec
97            }),
98            Value::I64(value) => TransmissionValue::I64({
99                let mut vec = VecDeque::new();
100                vec.push_back(value);
101                vec
102            }),
103            Value::I128(value) => TransmissionValue::I128({
104                let mut vec = VecDeque::new();
105                vec.push_back(value);
106                vec
107            }),
108
109            Value::U8(value) => TransmissionValue::U8({
110                let mut vec = VecDeque::new();
111                vec.push_back(value);
112                vec
113            }),
114            Value::U16(value) => TransmissionValue::U16({
115                let mut vec = VecDeque::new();
116                vec.push_back(value);
117                vec
118            }),
119            Value::U32(value) => TransmissionValue::U32({
120                let mut vec = VecDeque::new();
121                vec.push_back(value);
122                vec
123            }),
124            Value::U64(value) => TransmissionValue::U64({
125                let mut vec = VecDeque::new();
126                vec.push_back(value);
127                vec
128            }),
129            Value::U128(value) => TransmissionValue::U128({
130                let mut vec = VecDeque::new();
131                vec.push_back(value);
132                vec
133            }),
134
135            Value::F32(value) => TransmissionValue::F32({
136                let mut vec = VecDeque::new();
137                vec.push_back(value);
138                vec
139            }),
140            Value::F64(value) => TransmissionValue::F64({
141                let mut vec = VecDeque::new();
142                vec.push_back(value);
143                vec
144            }),
145
146            Value::Bool(value) => TransmissionValue::Bool({
147                let mut vec = VecDeque::new();
148                vec.push_back(value);
149                vec
150            }),
151            Value::Byte(value) => TransmissionValue::Byte({
152                let mut vec = VecDeque::new();
153                vec.push_back(value);
154                vec
155            }),
156            Value::Char(value) => TransmissionValue::Char({
157                let mut vec = VecDeque::new();
158                vec.push_back(value);
159                vec
160            }),
161            Value::String(value) => TransmissionValue::String({
162                let mut vec = VecDeque::new();
163                vec.push_back(value);
164                vec
165            }),
166
167            Value::Packed(PackedArray::I8(value)) => TransmissionValue::PackedI8({
168                let mut vec = VecDeque::new();
169                vec.push_back(value);
170                vec
171            }),
172            Value::Packed(PackedArray::I16(value)) => TransmissionValue::PackedI16({
173                let mut vec = VecDeque::new();
174                vec.push_back(value);
175                vec
176            }),
177            Value::Packed(PackedArray::I32(value)) => TransmissionValue::PackedI32({
178                let mut vec = VecDeque::new();
179                vec.push_back(value);
180                vec
181            }),
182            Value::Packed(PackedArray::I64(value)) => TransmissionValue::PackedI64({
183                let mut vec = VecDeque::new();
184                vec.push_back(value);
185                vec
186            }),
187            Value::Packed(PackedArray::I128(value)) => TransmissionValue::PackedI128({
188                let mut vec = VecDeque::new();
189                vec.push_back(value);
190                vec
191            }),
192            Value::Packed(PackedArray::U8(value)) => TransmissionValue::PackedU8({
193                let mut vec = VecDeque::new();
194                vec.push_back(value);
195                vec
196            }),
197            Value::Packed(PackedArray::U16(value)) => TransmissionValue::PackedU16({
198                let mut vec = VecDeque::new();
199                vec.push_back(value);
200                vec
201            }),
202            Value::Packed(PackedArray::U32(value)) => TransmissionValue::PackedU32({
203                let mut vec = VecDeque::new();
204                vec.push_back(value);
205                vec
206            }),
207            Value::Packed(PackedArray::U64(value)) => TransmissionValue::PackedU64({
208                let mut vec = VecDeque::new();
209                vec.push_back(value);
210                vec
211            }),
212            Value::Packed(PackedArray::U128(value)) => TransmissionValue::PackedU128({
213                let mut vec = VecDeque::new();
214                vec.push_back(value);
215                vec
216            }),
217            Value::Packed(PackedArray::F32(value)) => TransmissionValue::PackedF32({
218                let mut vec = VecDeque::new();
219                vec.push_back(value);
220                vec
221            }),
222            Value::Packed(PackedArray::F64(value)) => TransmissionValue::PackedF64({
223                let mut vec = VecDeque::new();
224                vec.push_back(value);
225                vec
226            }),
227            Value::Packed(PackedArray::Bool(value)) => TransmissionValue::PackedBool({
228                let mut vec = VecDeque::new();
229                vec.push_back(value);
230                vec
231            }),
232            Value::Packed(PackedArray::Byte(value)) => TransmissionValue::PackedByte({
233                let mut vec = VecDeque::new();
234                vec.push_back(value);
235                vec
236            }),
237            Value::Packed(PackedArray::Char(value)) => TransmissionValue::PackedChar({
238                let mut vec = VecDeque::new();
239                vec.push_back(value);
240                vec
241            }),
242
243            _ => TransmissionValue::Other({
244                let mut vec = VecDeque::new();
245                vec.push_back(value);
246                vec
247            }),
248        }
249    }
250
251    pub fn append(&mut self, values: TransmissionValue) {
252        match (self, values) {
253            (TransmissionValue::Void(data), TransmissionValue::Void(mut values)) => {
254                data.append(&mut values)
255            }
256            (TransmissionValue::I8(data), TransmissionValue::I8(mut values)) => {
257                data.append(&mut values)
258            }
259            (TransmissionValue::I16(data), TransmissionValue::I16(mut values)) => {
260                data.append(&mut values)
261            }
262            (TransmissionValue::I32(data), TransmissionValue::I32(mut values)) => {
263                data.append(&mut values)
264            }
265            (TransmissionValue::I64(data), TransmissionValue::I64(mut values)) => {
266                data.append(&mut values)
267            }
268            (TransmissionValue::I128(data), TransmissionValue::I128(mut values)) => {
269                data.append(&mut values)
270            }
271
272            (TransmissionValue::U8(data), TransmissionValue::U8(mut values)) => {
273                data.append(&mut values)
274            }
275            (TransmissionValue::U16(data), TransmissionValue::U16(mut values)) => {
276                data.append(&mut values)
277            }
278            (TransmissionValue::U32(data), TransmissionValue::U32(mut values)) => {
279                data.append(&mut values)
280            }
281            (TransmissionValue::U64(data), TransmissionValue::U64(mut values)) => {
282                data.append(&mut values)
283            }
284            (TransmissionValue::U128(data), TransmissionValue::U128(mut values)) => {
285                data.append(&mut values)
286            }
287
288            (TransmissionValue::F32(data), TransmissionValue::F32(mut values)) => {
289                data.append(&mut values)
290            }
291            (TransmissionValue::F64(data), TransmissionValue::F64(mut values)) => {
292                data.append(&mut values)
293            }
294
295            (TransmissionValue::Bool(data), TransmissionValue::Bool(mut values)) => {
296                data.append(&mut values)
297            }
298            (TransmissionValue::Byte(data), TransmissionValue::Byte(mut values)) => {
299                data.append(&mut values)
300            }
301            (TransmissionValue::Char(data), TransmissionValue::Char(mut values)) => {
302                data.append(&mut values)
303            }
304            (TransmissionValue::String(data), TransmissionValue::String(mut values)) => {
305                data.append(&mut values)
306            }
307
308            (TransmissionValue::PackedI8(data), TransmissionValue::PackedI8(mut values)) => {
309                data.append(&mut values)
310            }
311            (TransmissionValue::PackedI16(data), TransmissionValue::PackedI16(mut values)) => {
312                data.append(&mut values)
313            }
314            (TransmissionValue::PackedI32(data), TransmissionValue::PackedI32(mut values)) => {
315                data.append(&mut values)
316            }
317            (TransmissionValue::PackedI64(data), TransmissionValue::PackedI64(mut values)) => {
318                data.append(&mut values)
319            }
320            (TransmissionValue::PackedI128(data), TransmissionValue::PackedI128(mut values)) => {
321                data.append(&mut values)
322            }
323            (TransmissionValue::PackedU8(data), TransmissionValue::PackedU8(mut values)) => {
324                data.append(&mut values)
325            }
326            (TransmissionValue::PackedU16(data), TransmissionValue::PackedU16(mut values)) => {
327                data.append(&mut values)
328            }
329            (TransmissionValue::PackedU32(data), TransmissionValue::PackedU32(mut values)) => {
330                data.append(&mut values)
331            }
332            (TransmissionValue::PackedU64(data), TransmissionValue::PackedU64(mut values)) => {
333                data.append(&mut values)
334            }
335            (TransmissionValue::PackedU128(data), TransmissionValue::PackedU128(mut values)) => {
336                data.append(&mut values)
337            }
338            (TransmissionValue::PackedF32(data), TransmissionValue::PackedF32(mut values)) => {
339                data.append(&mut values)
340            }
341            (TransmissionValue::PackedF64(data), TransmissionValue::PackedF64(mut values)) => {
342                data.append(&mut values)
343            }
344            (TransmissionValue::PackedBool(data), TransmissionValue::PackedBool(mut values)) => {
345                data.append(&mut values)
346            }
347            (TransmissionValue::PackedByte(data), TransmissionValue::PackedByte(mut values)) => {
348                data.append(&mut values)
349            }
350            (TransmissionValue::PackedChar(data), TransmissionValue::PackedChar(mut values)) => {
351                data.append(&mut values)
352            }
353
354            (TransmissionValue::Other(data), TransmissionValue::Other(mut values)) => {
355                data.append(&mut values)
356            }
357            _ => panic!("Adding nonmatching values type in transmitter, aborting."),
358        }
359    }
360
361    pub fn len(&self) -> usize {
362        match self {
363            TransmissionValue::Void(data) => data.len(),
364            TransmissionValue::I8(data) => data.len(),
365            TransmissionValue::I16(data) => data.len(),
366            TransmissionValue::I32(data) => data.len(),
367            TransmissionValue::I64(data) => data.len(),
368            TransmissionValue::I128(data) => data.len(),
369            TransmissionValue::U8(data) => data.len(),
370            TransmissionValue::U16(data) => data.len(),
371            TransmissionValue::U32(data) => data.len(),
372            TransmissionValue::U64(data) => data.len(),
373            TransmissionValue::U128(data) => data.len(),
374            TransmissionValue::F32(data) => data.len(),
375            TransmissionValue::F64(data) => data.len(),
376            TransmissionValue::Bool(data) => data.len(),
377            TransmissionValue::Byte(data) => data.len(),
378            TransmissionValue::Char(data) => data.len(),
379            TransmissionValue::String(data) => data.len(),
380            TransmissionValue::PackedI8(data) => data.len(),
381            TransmissionValue::PackedI16(data) => data.len(),
382            TransmissionValue::PackedI32(data) => data.len(),
383            TransmissionValue::PackedI64(data) => data.len(),
384            TransmissionValue::PackedI128(data) => data.len(),
385            TransmissionValue::PackedU8(data) => data.len(),
386            TransmissionValue::PackedU16(data) => data.len(),
387            TransmissionValue::PackedU32(data) => data.len(),
388            TransmissionValue::PackedU64(data) => data.len(),
389            TransmissionValue::PackedU128(data) => data.len(),
390            TransmissionValue::PackedF32(data) => data.len(),
391            TransmissionValue::PackedF64(data) => data.len(),
392            TransmissionValue::PackedBool(data) => data.len(),
393            TransmissionValue::PackedByte(data) => data.len(),
394            TransmissionValue::PackedChar(data) => data.len(),
395            TransmissionValue::Other(data) => data.len(),
396        }
397    }
398
399    pub fn pop_front(&mut self) -> Option<Value> {
400        match self {
401            TransmissionValue::Void(data) => data.pop_front().map(|data| data.into()),
402            TransmissionValue::I8(data) => data.pop_front().map(|data| data.into()),
403            TransmissionValue::I16(data) => data.pop_front().map(|data| data.into()),
404            TransmissionValue::I32(data) => data.pop_front().map(|data| data.into()),
405            TransmissionValue::I64(data) => data.pop_front().map(|data| data.into()),
406            TransmissionValue::I128(data) => data.pop_front().map(|data| data.into()),
407            TransmissionValue::U8(data) => data.pop_front().map(|data| data.into()),
408            TransmissionValue::U16(data) => data.pop_front().map(|data| data.into()),
409            TransmissionValue::U32(data) => data.pop_front().map(|data| data.into()),
410            TransmissionValue::U64(data) => data.pop_front().map(|data| data.into()),
411            TransmissionValue::U128(data) => data.pop_front().map(|data| data.into()),
412            TransmissionValue::F32(data) => data.pop_front().map(|data| data.into()),
413            TransmissionValue::F64(data) => data.pop_front().map(|data| data.into()),
414            TransmissionValue::Bool(data) => data.pop_front().map(|data| data.into()),
415            TransmissionValue::Byte(data) => data.pop_front().map(|data| Value::Byte(data)),
416            TransmissionValue::Char(data) => data.pop_front().map(|data| data.into()),
417            TransmissionValue::String(data) => data.pop_front().map(|data| data.into()),
418            TransmissionValue::PackedI8(data) => data
419                .pop_front()
420                .map(|data| Value::Packed(PackedArray::I8(data))),
421            TransmissionValue::PackedI16(data) => data
422                .pop_front()
423                .map(|data| Value::Packed(PackedArray::I16(data))),
424            TransmissionValue::PackedI32(data) => data
425                .pop_front()
426                .map(|data| Value::Packed(PackedArray::I32(data))),
427            TransmissionValue::PackedI64(data) => data
428                .pop_front()
429                .map(|data| Value::Packed(PackedArray::I64(data))),
430            TransmissionValue::PackedI128(data) => data
431                .pop_front()
432                .map(|data| Value::Packed(PackedArray::I128(data))),
433            TransmissionValue::PackedU8(data) => data
434                .pop_front()
435                .map(|data| Value::Packed(PackedArray::U8(data))),
436            TransmissionValue::PackedU16(data) => data
437                .pop_front()
438                .map(|data| Value::Packed(PackedArray::U16(data))),
439            TransmissionValue::PackedU32(data) => data
440                .pop_front()
441                .map(|data| Value::Packed(PackedArray::U32(data))),
442            TransmissionValue::PackedU64(data) => data
443                .pop_front()
444                .map(|data| Value::Packed(PackedArray::U64(data))),
445            TransmissionValue::PackedU128(data) => data
446                .pop_front()
447                .map(|data| Value::Packed(PackedArray::U128(data))),
448            TransmissionValue::PackedF32(data) => data
449                .pop_front()
450                .map(|data| Value::Packed(PackedArray::F32(data))),
451            TransmissionValue::PackedF64(data) => data
452                .pop_front()
453                .map(|data| Value::Packed(PackedArray::F64(data))),
454            TransmissionValue::PackedBool(data) => data
455                .pop_front()
456                .map(|data| Value::Packed(PackedArray::Bool(data))),
457            TransmissionValue::PackedByte(data) => data
458                .pop_front()
459                .map(|data| Value::Packed(PackedArray::Byte(data))),
460            TransmissionValue::PackedChar(data) => data
461                .pop_front()
462                .map(|data| Value::Packed(PackedArray::Char(data))),
463            TransmissionValue::Other(data) => data.pop_front(),
464        }
465    }
466
467    /// Rough memory footprint of the whole batch, in bytes. See `Value::estimated_size`
468    /// for why this is an estimate rather than an exact figure. The optimized variants
469    /// (fixed-size scalars, packed `Byte`) are O(1); `String` and `Other` are O(n) since
470    /// their elements don't have a uniform size.
471    pub fn estimated_size(&self) -> usize {
472        match self {
473            TransmissionValue::Void(data) => data.len() * std::mem::size_of::<()>(),
474            TransmissionValue::I8(data) => data.len() * std::mem::size_of::<i8>(),
475            TransmissionValue::I16(data) => data.len() * std::mem::size_of::<i16>(),
476            TransmissionValue::I32(data) => data.len() * std::mem::size_of::<i32>(),
477            TransmissionValue::I64(data) => data.len() * std::mem::size_of::<i64>(),
478            TransmissionValue::I128(data) => data.len() * std::mem::size_of::<i128>(),
479            TransmissionValue::U8(data) => data.len() * std::mem::size_of::<u8>(),
480            TransmissionValue::U16(data) => data.len() * std::mem::size_of::<u16>(),
481            TransmissionValue::U32(data) => data.len() * std::mem::size_of::<u32>(),
482            TransmissionValue::U64(data) => data.len() * std::mem::size_of::<u64>(),
483            TransmissionValue::U128(data) => data.len() * std::mem::size_of::<u128>(),
484            TransmissionValue::F32(data) => data.len() * std::mem::size_of::<f32>(),
485            TransmissionValue::F64(data) => data.len() * std::mem::size_of::<f64>(),
486            TransmissionValue::Bool(data) => data.len() * std::mem::size_of::<bool>(),
487            TransmissionValue::Byte(data) => data.len(),
488            TransmissionValue::Char(data) => data.len() * std::mem::size_of::<char>(),
489            TransmissionValue::String(data) => data.iter().map(String::len).sum(),
490            TransmissionValue::PackedI8(data) => data
491                .iter()
492                .map(|arr| arr.len() * std::mem::size_of::<i8>())
493                .sum(),
494            TransmissionValue::PackedI16(data) => data
495                .iter()
496                .map(|arr| arr.len() * std::mem::size_of::<i16>())
497                .sum(),
498            TransmissionValue::PackedI32(data) => data
499                .iter()
500                .map(|arr| arr.len() * std::mem::size_of::<i32>())
501                .sum(),
502            TransmissionValue::PackedI64(data) => data
503                .iter()
504                .map(|arr| arr.len() * std::mem::size_of::<i64>())
505                .sum(),
506            TransmissionValue::PackedI128(data) => data
507                .iter()
508                .map(|arr| arr.len() * std::mem::size_of::<i128>())
509                .sum(),
510            TransmissionValue::PackedU8(data) => data
511                .iter()
512                .map(|arr| arr.len() * std::mem::size_of::<u8>())
513                .sum(),
514            TransmissionValue::PackedU16(data) => data
515                .iter()
516                .map(|arr| arr.len() * std::mem::size_of::<u16>())
517                .sum(),
518            TransmissionValue::PackedU32(data) => data
519                .iter()
520                .map(|arr| arr.len() * std::mem::size_of::<u32>())
521                .sum(),
522            TransmissionValue::PackedU64(data) => data
523                .iter()
524                .map(|arr| arr.len() * std::mem::size_of::<u64>())
525                .sum(),
526            TransmissionValue::PackedU128(data) => data
527                .iter()
528                .map(|arr| arr.len() * std::mem::size_of::<u128>())
529                .sum(),
530            TransmissionValue::PackedF32(data) => data
531                .iter()
532                .map(|arr| arr.len() * std::mem::size_of::<f32>())
533                .sum(),
534            TransmissionValue::PackedF64(data) => data
535                .iter()
536                .map(|arr| arr.len() * std::mem::size_of::<f64>())
537                .sum(),
538            TransmissionValue::PackedBool(data) => data
539                .iter()
540                .map(|arr| arr.len() * std::mem::size_of::<bool>())
541                .sum(),
542            TransmissionValue::PackedByte(data) => data.iter().map(|arr| arr.len()).sum(),
543            TransmissionValue::PackedChar(data) => data
544                .iter()
545                .map(|arr| arr.len() * std::mem::size_of::<char>())
546                .sum(),
547            TransmissionValue::Other(data) => data.iter().map(Value::estimated_size).sum(),
548        }
549    }
550
551    pub fn push(&mut self, value: Value) {
552        match (self, value) {
553            (TransmissionValue::Void(data), Value::Void(value)) => data.push_back(value),
554            (TransmissionValue::I8(data), Value::I8(value)) => data.push_back(value),
555            (TransmissionValue::I16(data), Value::I16(value)) => data.push_back(value),
556            (TransmissionValue::I32(data), Value::I32(value)) => data.push_back(value),
557            (TransmissionValue::I64(data), Value::I64(value)) => data.push_back(value),
558            (TransmissionValue::I128(data), Value::I128(value)) => data.push_back(value),
559
560            (TransmissionValue::U8(data), Value::U8(value)) => data.push_back(value),
561            (TransmissionValue::U16(data), Value::U16(value)) => data.push_back(value),
562            (TransmissionValue::U32(data), Value::U32(value)) => data.push_back(value),
563            (TransmissionValue::U64(data), Value::U64(value)) => data.push_back(value),
564            (TransmissionValue::U128(data), Value::U128(value)) => data.push_back(value),
565
566            (TransmissionValue::F32(data), Value::F32(value)) => data.push_back(value),
567            (TransmissionValue::F64(data), Value::F64(value)) => data.push_back(value),
568
569            (TransmissionValue::Bool(data), Value::Bool(value)) => data.push_back(value),
570            (TransmissionValue::Byte(data), Value::Byte(value)) => data.push_back(value),
571            (TransmissionValue::Char(data), Value::Char(value)) => data.push_back(value),
572            (TransmissionValue::String(data), Value::String(value)) => data.push_back(value),
573
574            (TransmissionValue::PackedI8(data), Value::Packed(PackedArray::I8(value))) => {
575                data.push_back(value)
576            }
577            (TransmissionValue::PackedI16(data), Value::Packed(PackedArray::I16(value))) => {
578                data.push_back(value)
579            }
580            (TransmissionValue::PackedI32(data), Value::Packed(PackedArray::I32(value))) => {
581                data.push_back(value)
582            }
583            (TransmissionValue::PackedI64(data), Value::Packed(PackedArray::I64(value))) => {
584                data.push_back(value)
585            }
586            (TransmissionValue::PackedI128(data), Value::Packed(PackedArray::I128(value))) => {
587                data.push_back(value)
588            }
589            (TransmissionValue::PackedU8(data), Value::Packed(PackedArray::U8(value))) => {
590                data.push_back(value)
591            }
592            (TransmissionValue::PackedU16(data), Value::Packed(PackedArray::U16(value))) => {
593                data.push_back(value)
594            }
595            (TransmissionValue::PackedU32(data), Value::Packed(PackedArray::U32(value))) => {
596                data.push_back(value)
597            }
598            (TransmissionValue::PackedU64(data), Value::Packed(PackedArray::U64(value))) => {
599                data.push_back(value)
600            }
601            (TransmissionValue::PackedU128(data), Value::Packed(PackedArray::U128(value))) => {
602                data.push_back(value)
603            }
604            (TransmissionValue::PackedF32(data), Value::Packed(PackedArray::F32(value))) => {
605                data.push_back(value)
606            }
607            (TransmissionValue::PackedF64(data), Value::Packed(PackedArray::F64(value))) => {
608                data.push_back(value)
609            }
610            (TransmissionValue::PackedBool(data), Value::Packed(PackedArray::Bool(value))) => {
611                data.push_back(value)
612            }
613            (TransmissionValue::PackedByte(data), Value::Packed(PackedArray::Byte(value))) => {
614                data.push_back(value)
615            }
616            (TransmissionValue::PackedChar(data), Value::Packed(PackedArray::Char(value))) => {
617                data.push_back(value)
618            }
619
620            (TransmissionValue::Other(data), value) => data.push_back(value),
621
622            _ => panic!("Adding nonmatching value type in transmitter, aborting."),
623        }
624    }
625}
626
627impl Into<VecDeque<Value>> for TransmissionValue {
628    fn into(self) -> VecDeque<Value> {
629        match self {
630            TransmissionValue::Void(data) => data.into_iter().map(|data| data.into()).collect(),
631            TransmissionValue::I8(data) => data.into_iter().map(|data| data.into()).collect(),
632            TransmissionValue::I16(data) => data.into_iter().map(|data| data.into()).collect(),
633            TransmissionValue::I32(data) => data.into_iter().map(|data| data.into()).collect(),
634            TransmissionValue::I64(data) => data.into_iter().map(|data| data.into()).collect(),
635            TransmissionValue::I128(data) => data.into_iter().map(|data| data.into()).collect(),
636            TransmissionValue::U8(data) => data.into_iter().map(|data| data.into()).collect(),
637            TransmissionValue::U16(data) => data.into_iter().map(|data| data.into()).collect(),
638            TransmissionValue::U32(data) => data.into_iter().map(|data| data.into()).collect(),
639            TransmissionValue::U64(data) => data.into_iter().map(|data| data.into()).collect(),
640            TransmissionValue::U128(data) => data.into_iter().map(|data| data.into()).collect(),
641            TransmissionValue::F32(data) => data.into_iter().map(|data| data.into()).collect(),
642            TransmissionValue::F64(data) => data.into_iter().map(|data| data.into()).collect(),
643            TransmissionValue::Bool(data) => data.into_iter().map(|data| data.into()).collect(),
644            TransmissionValue::Byte(data) => {
645                data.into_iter().map(|data| Value::Byte(data)).collect()
646            }
647            TransmissionValue::Char(data) => data.into_iter().map(|data| data.into()).collect(),
648            TransmissionValue::String(data) => data.into_iter().map(|data| data.into()).collect(),
649            TransmissionValue::PackedI8(data) => data
650                .into_iter()
651                .map(|data| Value::Packed(PackedArray::I8(data)))
652                .collect(),
653            TransmissionValue::PackedI16(data) => data
654                .into_iter()
655                .map(|data| Value::Packed(PackedArray::I16(data)))
656                .collect(),
657            TransmissionValue::PackedI32(data) => data
658                .into_iter()
659                .map(|data| Value::Packed(PackedArray::I32(data)))
660                .collect(),
661            TransmissionValue::PackedI64(data) => data
662                .into_iter()
663                .map(|data| Value::Packed(PackedArray::I64(data)))
664                .collect(),
665            TransmissionValue::PackedI128(data) => data
666                .into_iter()
667                .map(|data| Value::Packed(PackedArray::I128(data)))
668                .collect(),
669            TransmissionValue::PackedU8(data) => data
670                .into_iter()
671                .map(|data| Value::Packed(PackedArray::U8(data)))
672                .collect(),
673            TransmissionValue::PackedU16(data) => data
674                .into_iter()
675                .map(|data| Value::Packed(PackedArray::U16(data)))
676                .collect(),
677            TransmissionValue::PackedU32(data) => data
678                .into_iter()
679                .map(|data| Value::Packed(PackedArray::U32(data)))
680                .collect(),
681            TransmissionValue::PackedU64(data) => data
682                .into_iter()
683                .map(|data| Value::Packed(PackedArray::U64(data)))
684                .collect(),
685            TransmissionValue::PackedU128(data) => data
686                .into_iter()
687                .map(|data| Value::Packed(PackedArray::U128(data)))
688                .collect(),
689            TransmissionValue::PackedF32(data) => data
690                .into_iter()
691                .map(|data| Value::Packed(PackedArray::F32(data)))
692                .collect(),
693            TransmissionValue::PackedF64(data) => data
694                .into_iter()
695                .map(|data| Value::Packed(PackedArray::F64(data)))
696                .collect(),
697            TransmissionValue::PackedBool(data) => data
698                .into_iter()
699                .map(|data| Value::Packed(PackedArray::Bool(data)))
700                .collect(),
701            TransmissionValue::PackedByte(data) => data
702                .into_iter()
703                .map(|data| Value::Packed(PackedArray::Byte(data)))
704                .collect(),
705            TransmissionValue::PackedChar(data) => data
706                .into_iter()
707                .map(|data| Value::Packed(PackedArray::Char(data)))
708                .collect(),
709            TransmissionValue::Other(data) => data,
710        }
711    }
712}
713impl Into<Vec<Value>> for TransmissionValue {
714    fn into(self) -> Vec<Value> {
715        match self {
716            TransmissionValue::Void(data) => data.into_iter().map(|data| data.into()).collect(),
717            TransmissionValue::I8(data) => data.into_iter().map(|data| data.into()).collect(),
718            TransmissionValue::I16(data) => data.into_iter().map(|data| data.into()).collect(),
719            TransmissionValue::I32(data) => data.into_iter().map(|data| data.into()).collect(),
720            TransmissionValue::I64(data) => data.into_iter().map(|data| data.into()).collect(),
721            TransmissionValue::I128(data) => data.into_iter().map(|data| data.into()).collect(),
722            TransmissionValue::U8(data) => data.into_iter().map(|data| data.into()).collect(),
723            TransmissionValue::U16(data) => data.into_iter().map(|data| data.into()).collect(),
724            TransmissionValue::U32(data) => data.into_iter().map(|data| data.into()).collect(),
725            TransmissionValue::U64(data) => data.into_iter().map(|data| data.into()).collect(),
726            TransmissionValue::U128(data) => data.into_iter().map(|data| data.into()).collect(),
727            TransmissionValue::F32(data) => data.into_iter().map(|data| data.into()).collect(),
728            TransmissionValue::F64(data) => data.into_iter().map(|data| data.into()).collect(),
729            TransmissionValue::Bool(data) => data.into_iter().map(|data| data.into()).collect(),
730            TransmissionValue::Byte(data) => {
731                data.into_iter().map(|data| Value::Byte(data)).collect()
732            }
733            TransmissionValue::Char(data) => data.into_iter().map(|data| data.into()).collect(),
734            TransmissionValue::String(data) => data.into_iter().map(|data| data.into()).collect(),
735            TransmissionValue::PackedI8(data) => data
736                .into_iter()
737                .map(|data| Value::Packed(PackedArray::I8(data)))
738                .collect(),
739            TransmissionValue::PackedI16(data) => data
740                .into_iter()
741                .map(|data| Value::Packed(PackedArray::I16(data)))
742                .collect(),
743            TransmissionValue::PackedI32(data) => data
744                .into_iter()
745                .map(|data| Value::Packed(PackedArray::I32(data)))
746                .collect(),
747            TransmissionValue::PackedI64(data) => data
748                .into_iter()
749                .map(|data| Value::Packed(PackedArray::I64(data)))
750                .collect(),
751            TransmissionValue::PackedI128(data) => data
752                .into_iter()
753                .map(|data| Value::Packed(PackedArray::I128(data)))
754                .collect(),
755            TransmissionValue::PackedU8(data) => data
756                .into_iter()
757                .map(|data| Value::Packed(PackedArray::U8(data)))
758                .collect(),
759            TransmissionValue::PackedU16(data) => data
760                .into_iter()
761                .map(|data| Value::Packed(PackedArray::U16(data)))
762                .collect(),
763            TransmissionValue::PackedU32(data) => data
764                .into_iter()
765                .map(|data| Value::Packed(PackedArray::U32(data)))
766                .collect(),
767            TransmissionValue::PackedU64(data) => data
768                .into_iter()
769                .map(|data| Value::Packed(PackedArray::U64(data)))
770                .collect(),
771            TransmissionValue::PackedU128(data) => data
772                .into_iter()
773                .map(|data| Value::Packed(PackedArray::U128(data)))
774                .collect(),
775            TransmissionValue::PackedF32(data) => data
776                .into_iter()
777                .map(|data| Value::Packed(PackedArray::F32(data)))
778                .collect(),
779            TransmissionValue::PackedF64(data) => data
780                .into_iter()
781                .map(|data| Value::Packed(PackedArray::F64(data)))
782                .collect(),
783            TransmissionValue::PackedBool(data) => data
784                .into_iter()
785                .map(|data| Value::Packed(PackedArray::Bool(data)))
786                .collect(),
787            TransmissionValue::PackedByte(data) => data
788                .into_iter()
789                .map(|data| Value::Packed(PackedArray::Byte(data)))
790                .collect(),
791            TransmissionValue::PackedChar(data) => data
792                .into_iter()
793                .map(|data| Value::Packed(PackedArray::Char(data)))
794                .collect(),
795            TransmissionValue::Other(data) => data.into(),
796        }
797    }
798}
799
800// The conversions below (`From<VecDeque<T>>`, `From<Vec<T>>`, `TryInto<VecDeque<T>>`,
801// `TryInto<Vec<T>>`) follow the exact same shape for every scalar type that maps 1:1 to a
802// `TransmissionValue` variant, so they're generated rather than hand-duplicated per type —
803// see ticket #120. `U8` is the one exception kept hand-written below: it's not a clean 1:1
804// mapping, since `TryInto<Vec<u8>>`/`TryInto<VecDeque<u8>>` must also accept the `Byte`
805// variant (bytes and small unsigned integers are interchangeable on extraction), while
806// `Byte` itself has no corresponding `From` — it's only ever produced via `Value::Byte`
807// going through `TransmissionValue::new`/`push`, not through a top-level `From<Vec<u8>>`.
808macro_rules! transmission_scalar_type {
809    ($variant:ident, $ty:ty) => {
810        impl From<VecDeque<$ty>> for TransmissionValue {
811            fn from(value: VecDeque<$ty>) -> Self {
812                TransmissionValue::$variant(value)
813            }
814        }
815
816        impl From<Vec<$ty>> for TransmissionValue {
817            fn from(value: Vec<$ty>) -> Self {
818                TransmissionValue::$variant(value.into())
819            }
820        }
821
822        impl TryInto<VecDeque<$ty>> for TransmissionValue {
823            type Error = ();
824
825            fn try_into(self) -> Result<VecDeque<$ty>, Self::Error> {
826                match self {
827                    TransmissionValue::$variant(data) => Ok(data),
828                    TransmissionValue::Other(data) => {
829                        let mut vec = VecDeque::with_capacity(data.len());
830                        for val in data {
831                            if let Ok(val) = val.try_data() {
832                                vec.push_back(val);
833                            } else {
834                                return Err(());
835                            }
836                        }
837                        Ok(vec)
838                    }
839                    _ => Err(()),
840                }
841            }
842        }
843
844        impl TryInto<Vec<$ty>> for TransmissionValue {
845            type Error = ();
846
847            fn try_into(self) -> Result<Vec<$ty>, Self::Error> {
848                match self {
849                    TransmissionValue::$variant(data) => Ok(data.into()),
850                    TransmissionValue::Other(data) => {
851                        let mut vec = Vec::with_capacity(data.len());
852                        for val in data {
853                            if let Ok(val) = val.try_data() {
854                                vec.push(val);
855                            } else {
856                                return Err(());
857                            }
858                        }
859                        Ok(vec)
860                    }
861                    _ => Err(()),
862                }
863            }
864        }
865    };
866}
867
868transmission_scalar_type!(Void, ());
869transmission_scalar_type!(I8, i8);
870transmission_scalar_type!(I16, i16);
871transmission_scalar_type!(I32, i32);
872transmission_scalar_type!(I64, i64);
873transmission_scalar_type!(I128, i128);
874transmission_scalar_type!(U16, u16);
875transmission_scalar_type!(U32, u32);
876transmission_scalar_type!(U64, u64);
877transmission_scalar_type!(U128, u128);
878transmission_scalar_type!(F32, f32);
879transmission_scalar_type!(F64, f64);
880transmission_scalar_type!(Bool, bool);
881transmission_scalar_type!(Char, char);
882transmission_scalar_type!(String, String);
883
884impl From<VecDeque<u8>> for TransmissionValue {
885    fn from(value: VecDeque<u8>) -> Self {
886        TransmissionValue::U8(value)
887    }
888}
889
890impl From<Vec<u8>> for TransmissionValue {
891    fn from(value: Vec<u8>) -> Self {
892        TransmissionValue::U8(value.into())
893    }
894}
895
896impl TryInto<VecDeque<u8>> for TransmissionValue {
897    type Error = ();
898
899    fn try_into(self) -> Result<VecDeque<u8>, Self::Error> {
900        match self {
901            TransmissionValue::U8(data) => Ok(data),
902            TransmissionValue::Byte(data) => Ok(data),
903            TransmissionValue::Other(data) => {
904                let mut vec = VecDeque::with_capacity(data.len());
905                for val in data {
906                    if let Ok(val) = val.try_data() {
907                        vec.push_back(val);
908                    } else {
909                        return Err(());
910                    }
911                }
912                Ok(vec)
913            }
914            _ => Err(()),
915        }
916    }
917}
918
919impl TryInto<Vec<u8>> for TransmissionValue {
920    type Error = ();
921
922    fn try_into(self) -> Result<Vec<u8>, Self::Error> {
923        match self {
924            TransmissionValue::U8(data) => Ok(data.into()),
925            TransmissionValue::Byte(data) => Ok(data.into()),
926            TransmissionValue::Other(data) => {
927                let mut vec = Vec::with_capacity(data.len());
928                for val in data {
929                    if let Ok(val) = val.try_data() {
930                        vec.push(val);
931                    } else {
932                        return Err(());
933                    }
934                }
935                Ok(vec)
936            }
937            _ => Err(()),
938        }
939    }
940}
941
942// `Arc<Vec<T>>` counterpart of `transmission_scalar_type!` above, for the `Packed*`
943// variants: same generated shape (`From<VecDeque<_>>`, `From<Vec<_>>`, `TryInto<VecDeque<_>>`,
944// `TryInto<Vec<_>>`), one array per queue entry instead of one scalar. `U8`/`Byte` are
945// kept hand-written below for the same reason as their scalar counterparts: `From`
946// must stay unambiguous (always produces `PackedU8`), while extraction accepts both.
947macro_rules! transmission_packed_scalar_type {
948    ($variant:ident, $ty:ty) => {
949        impl From<VecDeque<Arc<Vec<$ty>>>> for TransmissionValue {
950            fn from(value: VecDeque<Arc<Vec<$ty>>>) -> Self {
951                TransmissionValue::$variant(value)
952            }
953        }
954
955        impl From<Vec<Arc<Vec<$ty>>>> for TransmissionValue {
956            fn from(value: Vec<Arc<Vec<$ty>>>) -> Self {
957                TransmissionValue::$variant(value.into())
958            }
959        }
960
961        impl TryInto<VecDeque<Arc<Vec<$ty>>>> for TransmissionValue {
962            type Error = ();
963
964            fn try_into(self) -> Result<VecDeque<Arc<Vec<$ty>>>, Self::Error> {
965                match self {
966                    TransmissionValue::$variant(data) => Ok(data),
967                    TransmissionValue::Other(data) => {
968                        let mut vec = VecDeque::with_capacity(data.len());
969                        for val in data {
970                            if let Ok(val) = val.try_data() {
971                                vec.push_back(val);
972                            } else {
973                                return Err(());
974                            }
975                        }
976                        Ok(vec)
977                    }
978                    _ => Err(()),
979                }
980            }
981        }
982
983        impl TryInto<Vec<Arc<Vec<$ty>>>> for TransmissionValue {
984            type Error = ();
985
986            fn try_into(self) -> Result<Vec<Arc<Vec<$ty>>>, Self::Error> {
987                match self {
988                    TransmissionValue::$variant(data) => Ok(data.into()),
989                    TransmissionValue::Other(data) => {
990                        let mut vec = Vec::with_capacity(data.len());
991                        for val in data {
992                            if let Ok(val) = val.try_data() {
993                                vec.push(val);
994                            } else {
995                                return Err(());
996                            }
997                        }
998                        Ok(vec)
999                    }
1000                    _ => Err(()),
1001                }
1002            }
1003        }
1004    };
1005}
1006
1007transmission_packed_scalar_type!(PackedI8, i8);
1008transmission_packed_scalar_type!(PackedI16, i16);
1009transmission_packed_scalar_type!(PackedI32, i32);
1010transmission_packed_scalar_type!(PackedI64, i64);
1011transmission_packed_scalar_type!(PackedI128, i128);
1012transmission_packed_scalar_type!(PackedU16, u16);
1013transmission_packed_scalar_type!(PackedU32, u32);
1014transmission_packed_scalar_type!(PackedU64, u64);
1015transmission_packed_scalar_type!(PackedU128, u128);
1016transmission_packed_scalar_type!(PackedF32, f32);
1017transmission_packed_scalar_type!(PackedF64, f64);
1018transmission_packed_scalar_type!(PackedBool, bool);
1019transmission_packed_scalar_type!(PackedChar, char);
1020
1021impl From<VecDeque<Arc<Vec<u8>>>> for TransmissionValue {
1022    fn from(value: VecDeque<Arc<Vec<u8>>>) -> Self {
1023        TransmissionValue::PackedU8(value)
1024    }
1025}
1026
1027impl From<Vec<Arc<Vec<u8>>>> for TransmissionValue {
1028    fn from(value: Vec<Arc<Vec<u8>>>) -> Self {
1029        TransmissionValue::PackedU8(value.into())
1030    }
1031}
1032
1033impl TryInto<VecDeque<Arc<Vec<u8>>>> for TransmissionValue {
1034    type Error = ();
1035
1036    fn try_into(self) -> Result<VecDeque<Arc<Vec<u8>>>, Self::Error> {
1037        match self {
1038            TransmissionValue::PackedU8(data) => Ok(data),
1039            TransmissionValue::PackedByte(data) => Ok(data),
1040            TransmissionValue::Other(data) => {
1041                let mut vec = VecDeque::with_capacity(data.len());
1042                for val in data {
1043                    if let Ok(val) = val.try_data() {
1044                        vec.push_back(val);
1045                    } else {
1046                        return Err(());
1047                    }
1048                }
1049                Ok(vec)
1050            }
1051            _ => Err(()),
1052        }
1053    }
1054}
1055
1056impl TryInto<Vec<Arc<Vec<u8>>>> for TransmissionValue {
1057    type Error = ();
1058
1059    fn try_into(self) -> Result<Vec<Arc<Vec<u8>>>, Self::Error> {
1060        match self {
1061            TransmissionValue::PackedU8(data) => Ok(data.into()),
1062            TransmissionValue::PackedByte(data) => Ok(data.into()),
1063            TransmissionValue::Other(data) => {
1064                let mut vec = Vec::with_capacity(data.len());
1065                for val in data {
1066                    if let Ok(val) = val.try_data() {
1067                        vec.push(val);
1068                    } else {
1069                        return Err(());
1070                    }
1071                }
1072                Ok(vec)
1073            }
1074            _ => Err(()),
1075        }
1076    }
1077}
1078
1079#[cfg(test)]
1080mod conversion_tests {
1081    use super::*;
1082
1083    // A macro-generated type, as a roundtrip sanity check on the generator itself.
1084    #[test]
1085    fn macro_generated_type_roundtrips() {
1086        let batch: TransmissionValue = vec![1i64, 2, 3].into();
1087        assert!(matches!(batch, TransmissionValue::I64(_)));
1088        let back: Vec<i64> = batch.try_into().unwrap();
1089        assert_eq!(back, vec![1, 2, 3]);
1090    }
1091
1092    // Values boxed as `Other` (e.g. after arriving through a non-optimized path) must
1093    // still extract correctly through the generated `TryInto`, via `Value::try_data`.
1094    #[test]
1095    fn macro_generated_type_extracts_from_other_variant() {
1096        let boxed = TransmissionValue::Other(VecDeque::from(vec![Value::I64(10), Value::I64(20)]));
1097        let extracted: Vec<i64> = boxed.try_into().unwrap();
1098        assert_eq!(extracted, vec![10, 20]);
1099    }
1100
1101    // Void's `()` payload exercises the macro too, not just numeric/string types.
1102    #[test]
1103    fn void_roundtrips_through_the_macro() {
1104        let batch: TransmissionValue = vec![(), (), ()].into();
1105        let back: Vec<()> = batch.try_into().unwrap();
1106        assert_eq!(back, vec![(), (), ()]);
1107    }
1108
1109    // `Packed*` variants, one array per tick — a macro-generated type as a roundtrip
1110    // sanity check on `transmission_packed_scalar_type!`.
1111    #[test]
1112    fn packed_macro_generated_type_roundtrips_preserving_tick_boundaries() {
1113        let tick_one: Arc<Vec<i64>> = Arc::from(vec![1, 2, 3]);
1114        let tick_two: Arc<Vec<i64>> = Arc::from(vec![4, 5]);
1115        let batch: TransmissionValue = vec![Arc::clone(&tick_one), Arc::clone(&tick_two)].into();
1116        assert!(matches!(batch, TransmissionValue::PackedI64(_)));
1117        assert_eq!(batch.len(), 2);
1118        let back: Vec<Arc<Vec<i64>>> = batch.try_into().unwrap();
1119        assert_eq!(back, vec![tick_one, tick_two]);
1120    }
1121
1122    // `push`/`pop_front`/`new` round-trip through `Value::Packed`, exactly as a real
1123    // `Output`/`Input` channel would use them.
1124    #[test]
1125    fn packed_value_roundtrips_through_new_push_and_pop_front() {
1126        let mut batch =
1127            TransmissionValue::new(Value::Packed(PackedArray::Byte(Arc::from(vec![1u8, 2, 3]))));
1128        batch.push(Value::Packed(PackedArray::Byte(Arc::from(vec![4u8, 5]))));
1129        assert_eq!(batch.len(), 2);
1130        assert_eq!(
1131            batch.pop_front(),
1132            Some(Value::Packed(PackedArray::Byte(Arc::from(vec![1u8, 2, 3]))))
1133        );
1134        assert_eq!(
1135            batch.pop_front(),
1136            Some(Value::Packed(PackedArray::Byte(Arc::from(vec![4u8, 5]))))
1137        );
1138        assert_eq!(batch.pop_front(), None);
1139    }
1140
1141    // This is the packed counterpart of `u8_extraction_accepts_both_u8_and_byte_variants`
1142    // below: extraction must accept both `PackedU8` and `PackedByte`, even though only
1143    // `PackedU8` is ever produced by `From`.
1144    #[test]
1145    fn packed_u8_extraction_accepts_both_packed_u8_and_packed_byte_variants() {
1146        let as_u8 = TransmissionValue::PackedU8(VecDeque::from(vec![Arc::from(vec![1u8, 2, 3])]));
1147        let as_byte =
1148            TransmissionValue::PackedByte(VecDeque::from(vec![Arc::from(vec![4u8, 5, 6])]));
1149
1150        let from_u8: Vec<Arc<Vec<u8>>> = as_u8.try_into().unwrap();
1151        let from_byte: Vec<Arc<Vec<u8>>> = as_byte.try_into().unwrap();
1152
1153        assert_eq!(from_u8, vec![Arc::from(vec![1u8, 2, 3])]);
1154        assert_eq!(from_byte, vec![Arc::from(vec![4u8, 5, 6])]);
1155    }
1156
1157    #[test]
1158    fn packed_construction_always_produces_packed_u8_not_packed_byte() {
1159        let batch: TransmissionValue = vec![Arc::<Vec<u8>>::from(vec![1u8, 2, 3])].into();
1160        assert!(matches!(batch, TransmissionValue::PackedU8(_)));
1161    }
1162
1163    // This is the one case the ticket kept hand-written rather than folding into the
1164    // macro: extraction must accept both `U8` and `Byte`, even though only `U8` is ever
1165    // produced by `From`. Losing either arm here would silently break byte-stream reads.
1166    #[test]
1167    fn u8_extraction_accepts_both_u8_and_byte_variants() {
1168        let as_u8 = TransmissionValue::U8(VecDeque::from(vec![1u8, 2, 3]));
1169        let as_byte = TransmissionValue::Byte(VecDeque::from(vec![4u8, 5, 6]));
1170
1171        let from_u8: Vec<u8> = as_u8.try_into().unwrap();
1172        let from_byte: Vec<u8> = as_byte.try_into().unwrap();
1173
1174        assert_eq!(from_u8, vec![1, 2, 3]);
1175        assert_eq!(from_byte, vec![4, 5, 6]);
1176    }
1177
1178    // From<Vec<u8>> must still only ever produce U8, never Byte — that asymmetry is
1179    // exactly why U8 couldn't go through the generic macro.
1180    #[test]
1181    fn u8_construction_always_produces_u8_variant_not_byte() {
1182        let batch: TransmissionValue = vec![1u8, 2, 3].into();
1183        assert!(matches!(batch, TransmissionValue::U8(_)));
1184    }
1185
1186    #[test]
1187    fn mismatched_type_extraction_fails() {
1188        let batch = TransmissionValue::I64(VecDeque::from(vec![1]));
1189        let result: Result<Vec<String>, ()> = batch.try_into();
1190        assert!(result.is_err());
1191    }
1192}
1193
1194impl From<VecDeque<Arc<dyn Data>>> for TransmissionValue {
1195    fn from(value: VecDeque<Arc<dyn Data>>) -> Self {
1196        TransmissionValue::Other(value.into_iter().map(|value| value.into()).collect())
1197    }
1198}
1199
1200impl From<Vec<Arc<dyn Data>>> for TransmissionValue {
1201    fn from(value: Vec<Arc<dyn Data>>) -> Self {
1202        TransmissionValue::Other(value.into_iter().map(|value| value.into()).collect())
1203    }
1204}
1205
1206impl TryInto<VecDeque<Arc<dyn Data>>> for TransmissionValue {
1207    type Error = ();
1208
1209    fn try_into(self) -> Result<VecDeque<Arc<dyn Data>>, Self::Error> {
1210        match self {
1211            TransmissionValue::Other(data) => {
1212                let mut vec = VecDeque::with_capacity(data.len());
1213                for val in data {
1214                    if let Ok(val) = val.try_data() {
1215                        vec.push_back(val);
1216                    } else {
1217                        return Err(());
1218                    }
1219                }
1220                Ok(vec)
1221            }
1222            _ => Err(()),
1223        }
1224    }
1225}
1226
1227impl TryInto<Vec<Arc<dyn Data>>> for TransmissionValue {
1228    type Error = ();
1229
1230    fn try_into(self) -> Result<Vec<Arc<dyn Data>>, Self::Error> {
1231        match self {
1232            TransmissionValue::Other(data) => {
1233                let mut vec = Vec::with_capacity(data.len());
1234                for val in data {
1235                    if let Ok(val) = val.try_data() {
1236                        vec.push(val);
1237                    } else {
1238                        return Err(());
1239                    }
1240                }
1241                Ok(vec)
1242            }
1243            _ => Err(()),
1244        }
1245    }
1246}
1247
1248/// Generic counterpart to the `Arc<dyn Data>` impls above, for a concrete `Data`
1249/// implementor `D` — mirrors `GetData<Arc<D>> for Value` (see `value/data.rs`) at the
1250/// batch level, so `recv_many_as::<Arc<D>>()` works the same way `recv_one_as::<Arc<D>>()`
1251/// already does. Coexists with the `Arc<dyn Data>` impls above for the same reason
1252/// `GetData<Arc<D>>` coexists with `GetData<Arc<dyn Data>>`: `D` carries an implicit
1253/// `Sized` bound here, which the unsized `dyn Data` can never satisfy.
1254impl<D: Data> From<VecDeque<Arc<D>>> for TransmissionValue {
1255    fn from(value: VecDeque<Arc<D>>) -> Self {
1256        TransmissionValue::Other(
1257            value
1258                .into_iter()
1259                .map(|value| (value as Arc<dyn Data>).into())
1260                .collect(),
1261        )
1262    }
1263}
1264
1265impl<D: Data> From<Vec<Arc<D>>> for TransmissionValue {
1266    fn from(value: Vec<Arc<D>>) -> Self {
1267        TransmissionValue::Other(
1268            value
1269                .into_iter()
1270                .map(|value| (value as Arc<dyn Data>).into())
1271                .collect(),
1272        )
1273    }
1274}
1275
1276impl<D: Data> TryInto<VecDeque<Arc<D>>> for TransmissionValue {
1277    type Error = ();
1278
1279    fn try_into(self) -> Result<VecDeque<Arc<D>>, Self::Error> {
1280        match self {
1281            TransmissionValue::Other(data) => {
1282                let mut vec = VecDeque::with_capacity(data.len());
1283                for val in data {
1284                    if let Ok(val) = val.try_data::<Arc<D>>() {
1285                        vec.push_back(val);
1286                    } else {
1287                        return Err(());
1288                    }
1289                }
1290                Ok(vec)
1291            }
1292            _ => Err(()),
1293        }
1294    }
1295}
1296
1297impl<D: Data> TryInto<Vec<Arc<D>>> for TransmissionValue {
1298    type Error = ();
1299
1300    fn try_into(self) -> Result<Vec<Arc<D>>, Self::Error> {
1301        match self {
1302            TransmissionValue::Other(data) => {
1303                let mut vec = Vec::with_capacity(data.len());
1304                for val in data {
1305                    if let Ok(val) = val.try_data::<Arc<D>>() {
1306                        vec.push(val);
1307                    } else {
1308                        return Err(());
1309                    }
1310                }
1311                Ok(vec)
1312            }
1313            _ => Err(()),
1314        }
1315    }
1316}
1317
1318#[cfg(test)]
1319mod estimated_size_tests {
1320    use super::*;
1321
1322    #[test]
1323    fn packed_byte_variant_costs_one_byte_per_element() {
1324        let batch = TransmissionValue::Byte(VecDeque::from(vec![0u8; 4096]));
1325        assert_eq!(batch.estimated_size(), 4096);
1326    }
1327
1328    #[test]
1329    fn fixed_size_scalar_variant_scales_with_type_size() {
1330        let batch = TransmissionValue::U64(VecDeque::from(vec![0u64; 10]));
1331        assert_eq!(batch.estimated_size(), 10 * std::mem::size_of::<u64>());
1332    }
1333
1334    #[test]
1335    fn string_variant_sums_actual_string_lengths() {
1336        let batch =
1337            TransmissionValue::String(VecDeque::from(vec!["ab".to_string(), "cde".to_string()]));
1338        assert_eq!(batch.estimated_size(), 2 + 3);
1339    }
1340
1341    #[test]
1342    fn other_variant_delegates_to_value_estimated_size() {
1343        let batch = TransmissionValue::Other(VecDeque::from(vec![Value::Byte(1), Value::Byte(2)]));
1344        assert_eq!(batch.estimated_size(), 2 * std::mem::size_of::<Value>());
1345    }
1346
1347    #[test]
1348    fn packed_byte_variant_sums_every_arrays_length_with_no_per_element_overhead() {
1349        let batch = TransmissionValue::PackedByte(VecDeque::from(vec![
1350            Arc::from(vec![0u8; 4096]),
1351            Arc::from(vec![0u8; 10]),
1352        ]));
1353        assert_eq!(batch.estimated_size(), 4096 + 10);
1354    }
1355
1356    #[test]
1357    fn packed_fixed_size_scalar_variant_scales_with_type_size() {
1358        let batch = TransmissionValue::PackedF64(VecDeque::from(vec![Arc::from(vec![0f64; 10])]));
1359        assert_eq!(batch.estimated_size(), 10 * std::mem::size_of::<f64>());
1360    }
1361
1362    #[test]
1363    fn packed_variant_len_counts_ticks_not_elements() {
1364        // `len()` here means "how many arrays are queued", the same "one entry per
1365        // stream tick" meaning it has for the scalar variants - not the total element
1366        // count across every array, which is a different, tick-boundary-preserving
1367        // shape than a flat scalar `VecDeque<u8>` would have.
1368        let batch = TransmissionValue::PackedByte(VecDeque::from(vec![
1369            Arc::from(vec![1u8, 2, 3]),
1370            Arc::from(vec![4u8, 5]),
1371        ]));
1372        assert_eq!(batch.len(), 2);
1373    }
1374}