1#![doc = include_str!("sysex7/README.md")]
2
3use crate::{
4 detail::{common_properties, helpers as message_helpers, BitOps},
5 traits::{Sysex, SysexInternal},
6 ux::{self, u7},
7};
8
9mod packet;
10
11pub use packet::Packet;
12
13pub(crate) const UMP_MESSAGE_TYPE: u8 = 0x3;
14
15#[midi2_proc::generate_message(MinSizeUmp(2), MinSizeBytes(2))]
16struct Sysex7 {
19 #[property(common_properties::UmpMessageTypeProperty<UMP_MESSAGE_TYPE>)]
20 ump_type: (),
21 #[property(Sysex7BytesBeginByte)]
22 bytes_begin_byte: (),
23 #[property(Sysex7BytesEndByte)]
24 bytes_end_byte: (),
25 #[property(ConsistentStatuses)]
26 consistent_statuses: (),
27 #[property(ValidPacketSizes)]
28 valid_packet_sizes: (),
29 #[property(GroupProperty)]
30 group: crate::ux::u4,
31 #[property(SysexPayloadPlaceholder)]
32 #[readonly]
33 #[writeonly]
34 sysex_payload: (),
35}
36
37const ERR_NO_BEGIN_BYTE: &str = "Sysex messages should begin 0xF0";
38const ERR_NO_END_BYTE: &str = "Sysex messages should end 0xF7";
39const ERR_INVALID_PACKET_SIZE: &str = "Size field can not exceed 6";
40
41const START_BYTE: u8 = 0xF0;
42const END_BYTE: u8 = 0xF7;
43
44struct Sysex7BytesBeginByte;
48
49impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for Sysex7BytesBeginByte {
50 type Type = ();
51}
52
53impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
54 for Sysex7BytesBeginByte
55{
56 fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
57 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
58 crate::buffer::UNIT_ID_U8 => {
59 if buffer.specialise_u8()[0] != START_BYTE {
60 Err(crate::error::InvalidData(ERR_NO_BEGIN_BYTE))
61 } else {
62 Ok(())
63 }
64 }
65 crate::buffer::UNIT_ID_U32 => Ok(()),
66 _ => unreachable!(),
67 }
68 }
69 fn read(_buffer: &'a B) -> Self::Type {}
70}
71
72impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
73 for Sysex7BytesBeginByte
74{
75 fn write(buffer: &mut B, _: Self::Type) {
76 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
77 buffer.specialise_u8_mut()[0] = START_BYTE;
78 }
79 }
80 fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
81 Ok(())
82 }
83 fn default() -> Self::Type {}
84}
85
86struct Sysex7BytesEndByte;
87
88impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for Sysex7BytesEndByte {
89 type Type = ();
90}
91
92impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
93 for Sysex7BytesEndByte
94{
95 fn read(_buffer: &'a B) -> Self::Type {}
96 fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
97 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
98 crate::buffer::UNIT_ID_U8 => buffer
99 .specialise_u8()
100 .iter()
101 .position(|b| *b == 0xF7)
102 .map(|_| ())
103 .ok_or(crate::error::InvalidData(ERR_NO_END_BYTE)),
104 crate::buffer::UNIT_ID_U32 => Ok(()),
105 _ => unreachable!(),
106 }
107 }
108}
109
110impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
111 for Sysex7BytesEndByte
112{
113 fn write(buffer: &mut B, _: Self::Type) {
114 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
115 buffer.specialise_u8_mut()[1] = END_BYTE;
118 }
119 }
120 fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
121 Ok(())
122 }
123 fn default() -> Self::Type {}
124}
125struct ConsistentStatuses;
126
127impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for ConsistentStatuses {
128 type Type = ();
129}
130
131impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
132 for ConsistentStatuses
133{
134 fn read(_buffer: &'a B) -> Self::Type {}
135 fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
136 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
137 message_helpers::validate_sysex_group_statuses(
138 buffer.specialise_u32(),
139 |p| u8::from(p[0].nibble(2)) == 0x0,
140 |p| u8::from(p[0].nibble(2)) == 0x1,
141 |p| u8::from(p[0].nibble(2)) == 0x2,
142 |p| u8::from(p[0].nibble(2)) == 0x3,
143 2,
144 crate::ux::u4::new(UMP_MESSAGE_TYPE),
145 )?;
146 }
147 Ok(())
148 }
149}
150
151impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
152 for ConsistentStatuses
153{
154 fn write(_: &mut B, _: Self::Type) {}
155 fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
156 Ok(())
157 }
158 fn default() -> Self::Type {}
159}
160
161struct ValidPacketSizes;
162
163impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for ValidPacketSizes {
164 type Type = ();
165}
166
167impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
168 for ValidPacketSizes
169{
170 fn read(_buffer: &'a B) -> Self::Type {}
171 fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
172 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
173 if buffer
174 .specialise_u32()
175 .chunks_exact(2)
176 .any(|p| u8::from(p[0].nibble(3)) > 6)
177 {
178 Err(crate::error::InvalidData(ERR_INVALID_PACKET_SIZE))
179 } else {
180 Ok(())
181 }
182 } else {
183 Ok(())
184 }
185 }
186}
187
188impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
189 for ValidPacketSizes
190{
191 fn write(_buffer: &mut B, _v: Self::Type) {}
192 fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
193 Ok(())
194 }
195 fn default() -> Self::Type {}
196}
197
198struct GroupProperty;
199
200impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for GroupProperty {
201 type Type = ux::u4;
202}
203
204impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B> for GroupProperty {
205 fn read(buffer: &'a B) -> Self::Type {
206 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
207 buffer.specialise_u32()[0].nibble(1)
208 } else {
209 Default::default()
210 }
211 }
212 fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
213 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
214 message_helpers::sysex_group_consistent_groups(
215 buffer.specialise_u32(),
216 2,
217 crate::ux::u4::new(UMP_MESSAGE_TYPE),
218 )
219 } else {
220 Ok(())
221 }
222 }
223}
224
225impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
226 for GroupProperty
227{
228 fn write(buffer: &mut B, group: Self::Type) {
229 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
230 const TYPE: ux::u4 = ux::u4::new(UMP_MESSAGE_TYPE);
231 for packet in buffer
232 .specialise_u32_mut()
233 .chunks_exact_mut(2)
234 .take_while(|packet| packet[0].nibble(0) == TYPE)
235 {
236 packet[0].set_nibble(1, group);
237 }
238 }
239 }
240 fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
241 Ok(())
242 }
243 fn default() -> Self::Type {
244 Default::default()
245 }
246}
247
248#[allow(dead_code)]
249struct SysexPayloadPlaceholder;
250
251impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for SysexPayloadPlaceholder {
252 type Type = ();
253}
254
255impl<B: crate::buffer::Buffer> crate::traits::Size<B> for Sysex7<B> {
259 fn size(&self) -> usize {
260 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
261 crate::buffer::UNIT_ID_U8 => {
262 self.0
263 .specialise_u8()
264 .iter()
265 .position(|b| *b == 0xF7)
266 .expect("Message is in an invalid state. No end byte.")
267 + 1
268 }
269 crate::buffer::UNIT_ID_U32 => {
270 self.0
271 .specialise_u32()
272 .chunks_exact(2)
273 .position(|p| {
274 let status: u8 = p[0].nibble(2).into();
275 status == 0x0 || status == 0x3
276 })
277 .expect("Message is in an invalid state. Couldn't find end packet.")
278 * 2
279 + 2
280 }
281 _ => unreachable!(),
282 }
283 }
284}
285
286impl<
287 A: crate::buffer::Bytes,
288 B: crate::buffer::Ump
289 + crate::buffer::BufferMut
290 + crate::buffer::BufferDefault
291 + crate::buffer::BufferResize,
292 > crate::traits::FromBytes<Sysex7<A>> for Sysex7<B>
293{
294 fn from_bytes(other: Sysex7<A>) -> Self {
295 try_from_other(
296 &other,
297 |s: &mut B, sz| {
298 s.resize(sz);
299 Ok(())
300 },
301 |s, p| {
302 s.set_payload(p);
303 Ok(())
304 },
305 )
306 .unwrap()
307 }
308}
309
310impl<
311 A: crate::buffer::Ump,
312 B: crate::buffer::Bytes
313 + crate::buffer::BufferMut
314 + crate::buffer::BufferDefault
315 + crate::buffer::BufferResize,
316 > crate::traits::FromUmp<Sysex7<A>> for Sysex7<B>
317{
318 fn from_ump(other: Sysex7<A>) -> Self {
319 try_from_other(
320 &other,
321 |s: &mut B, sz| {
322 s.resize(sz);
323 Ok(())
324 },
325 |s, p| {
326 s.set_payload(p);
327 Ok(())
328 },
329 )
330 .unwrap()
331 }
332}
333
334impl<
335 A: crate::buffer::Bytes,
336 B: crate::buffer::Ump
337 + crate::buffer::BufferMut
338 + crate::buffer::BufferDefault
339 + crate::buffer::BufferTryResize,
340 > crate::traits::TryFromBytes<Sysex7<A>> for Sysex7<B>
341{
342 fn try_from_bytes(other: Sysex7<A>) -> Result<Self, crate::error::BufferOverflow> {
343 try_from_other(
344 &other,
345 |s: &mut B, sz| s.try_resize(sz),
346 |s, p| s.try_set_payload(p),
347 )
348 }
349}
350
351impl<
352 A: crate::buffer::Ump,
353 B: crate::buffer::Bytes
354 + crate::buffer::BufferMut
355 + crate::buffer::BufferDefault
356 + crate::buffer::BufferTryResize,
357 > crate::traits::TryFromUmp<Sysex7<A>> for Sysex7<B>
358{
359 fn try_from_ump(other: Sysex7<A>) -> Result<Self, crate::error::BufferOverflow> {
360 try_from_other(
361 &other,
362 |s: &mut B, sz| s.try_resize(sz),
363 |s, p| s.try_set_payload(p),
364 )
365 }
366}
367
368fn try_from_other<
369 A: crate::buffer::Buffer,
370 B: crate::buffer::Buffer + crate::buffer::BufferMut + crate::buffer::BufferDefault,
371 R: Fn(&mut B, usize) -> Result<(), crate::error::BufferOverflow>,
372 S: Fn(&mut Sysex7<B>, PayloadIterator<A::Unit>) -> Result<(), crate::error::BufferOverflow>,
373>(
374 other: &Sysex7<A>,
375 try_resize: R,
376 try_set_payload: S,
377) -> Result<Sysex7<B>, crate::error::BufferOverflow> {
378 let mut buffer = <B as crate::buffer::BufferDefault>::default();
379 try_resize(
380 &mut buffer,
381 <Sysex7<B> as crate::traits::MinSize<B>>::MIN_SIZE,
382 )?;
383
384 convert_generated_properties(&other.0, &mut buffer);
385
386 let mut ret = Sysex7::<B>(buffer);
388 try_set_payload(&mut ret, other.payload())?;
389
390 Ok(ret)
391}
392
393fn convert_generated_properties<
394 A: crate::buffer::Buffer,
395 B: crate::buffer::Buffer + crate::buffer::BufferMut,
396>(
397 buffer_a: &A,
398 buffer_b: &mut B,
399) {
400 type MessageType = common_properties::UmpMessageTypeProperty<UMP_MESSAGE_TYPE>;
401 <MessageType as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
402 <Sysex7BytesBeginByte as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
403 <Sysex7BytesEndByte as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
404 <ConsistentStatuses as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
405 <ValidPacketSizes as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
406 <GroupProperty as crate::detail::property::WriteProperty<B>>::write(
407 buffer_b,
408 <GroupProperty as crate::detail::property::ReadProperty<A>>::read(buffer_a),
409 );
410}
411
412impl<B: crate::buffer::Buffer> Sysex<B> for Sysex7<B> {
413 type Byte = ux::u7;
414 type PayloadIterator<'a>
415 = PayloadIterator<'a, B::Unit>
416 where
417 B::Unit: 'a,
418 Self: 'a;
419
420 fn payload<'a>(&'a self) -> Self::PayloadIterator<'a>
421 where
422 B::Unit: 'a,
423 {
424 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
425 crate::buffer::UNIT_ID_U8 => PayloadIterator {
426 data: &self.0.buffer()[1..self.data().len() - 1],
427 payload_index: 0,
428 packet_index: 0,
429 size_cache: 0,
430 },
431 crate::buffer::UNIT_ID_U32 => {
432 let size_cache = self
433 .data()
434 .specialise_u32()
435 .chunks_exact(2)
436 .map(PayloadIterator::<B::Unit>::packet_size)
437 .sum::<usize>();
438 PayloadIterator {
439 data: self.0.buffer(),
440 payload_index: 0,
441 packet_index: 0,
442 size_cache,
443 }
444 }
445 _ => unreachable!(),
446 }
447 }
448
449 fn set_payload<D>(&mut self, data: D)
450 where
451 D: core::iter::Iterator<Item = Self::Byte>,
452 B: crate::buffer::BufferMut + crate::buffer::BufferResize,
453 {
454 <Self as SysexInternal<B>>::resize(self, 0);
455 self.insert_payload(data, 0);
456 }
457
458 fn try_set_payload<D>(
459 &mut self,
460 data: D,
461 ) -> core::result::Result<(), crate::error::BufferOverflow>
462 where
463 D: core::iter::Iterator<Item = Self::Byte>,
464 B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
465 {
466 <Self as SysexInternal<B>>::try_resize(self, 0)?;
467 self.try_insert_payload(data, 0)
468 }
469
470 fn set_byte(&mut self, byte: ux::u7, mut index: usize)
471 where
472 B: crate::buffer::BufferMut,
473 {
474 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
475 crate::buffer::UNIT_ID_U8 => {
476 let buffer = self.buffer_access_mut().specialise_u8_mut();
477 buffer[index + 1].set_septet(0, byte);
478 }
479 crate::buffer::UNIT_ID_U32 => {
480 let buffer = self.buffer_access_mut().specialise_u32_mut();
483 let mut packet_index = 0;
484 loop {
485 let sz = (u8::from(buffer[packet_index * 2].nibble(3))) as usize;
486 if index < sz {
487 buffer[packet_index * 2 + (index + 2) / 4]
488 .set_septet((index + 2) % 4, byte);
489 break;
490 }
491 index -= sz;
492 packet_index += 1;
493 }
494 }
495 _ => unreachable!(),
496 }
497 }
498
499 fn splice_payload<D, R>(&mut self, data: D, range: R)
500 where
501 D: core::iter::Iterator<Item = Self::Byte>,
502 B: crate::buffer::BufferMut + crate::buffer::BufferResize,
503 R: core::ops::RangeBounds<usize>,
504 {
505 message_helpers::splice_sysex_data(self, data, range)
506 }
507
508 fn try_splice_payload<D, R>(
509 &mut self,
510 data: D,
511 range: R,
512 ) -> core::result::Result<(), crate::error::BufferOverflow>
513 where
514 D: core::iter::Iterator<Item = Self::Byte>,
515 B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
516 R: core::ops::RangeBounds<usize>,
517 {
518 message_helpers::try_splice_sysex_data(self, data, range)
519 }
520
521 fn payload_size(&self) -> usize {
522 self.payload().len()
523 }
524}
525
526impl<B: crate::buffer::Buffer> SysexInternal<B> for Sysex7<B> {
527 fn resize(&mut self, payload_size: usize)
528 where
529 B: crate::buffer::BufferMut + crate::buffer::BufferResize,
530 {
531 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
532 crate::buffer::UNIT_ID_U8 => {
533 let buffer_sz = payload_size + 2;
534 let old_payload_size = self.payload_size();
535 self.0.resize(buffer_sz);
536 if payload_size > old_payload_size {
537 self.0.specialise_u8_mut()[old_payload_size + 1] = 0;
539 }
540 self.0.specialise_u8_mut()[buffer_sz - 1] = END_BYTE;
541 }
542 crate::buffer::UNIT_ID_U32 => try_resize_ump(self, payload_size, |s, sz| {
543 s.0.resize(sz);
544 Ok(())
545 })
546 .unwrap(),
547 _ => unreachable!(),
548 }
549 }
550
551 fn try_resize(
552 &mut self,
553 payload_size: usize,
554 ) -> core::result::Result<(), crate::traits::SysexTryResizeError>
555 where
556 B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
557 {
558 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
559 crate::buffer::UNIT_ID_U8 => {
560 let old_payload_size = self.payload_size();
561 let mut buffer_sz = payload_size + 2;
562 let result = self.0.try_resize(buffer_sz).map_err(|_| {
563 buffer_sz = self.0.buffer().len();
564 crate::traits::SysexTryResizeError(buffer_sz.saturating_sub(2))
565 });
566 if buffer_sz > old_payload_size {
567 self.0.specialise_u8_mut()[old_payload_size + 1] = 0;
569 }
570 self.0.specialise_u8_mut()[buffer_sz - 1] = END_BYTE;
571 result
572 }
573 crate::buffer::UNIT_ID_U32 => {
574 try_resize_ump(self, payload_size, |s, sz| s.0.try_resize(sz))
575 }
576 _ => unreachable!(),
577 }
578 }
579
580 fn write_datum(&mut self, datum: Self::Byte, payload_index: usize)
581 where
582 B: crate::buffer::BufferMut,
583 {
584 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
585 crate::buffer::UNIT_ID_U8 => {
586 self.0.specialise_u8_mut()[payload_index + 1] = datum.into();
587 }
588 crate::buffer::UNIT_ID_U32 => {
589 let buffer_index = 2 * (payload_index / 6);
592 let byte_index = payload_index % 6;
593 self.0.specialise_u32_mut()[buffer_index + (byte_index + 2) / 4]
594 .set_septet((byte_index + 2) % 4, datum);
595 }
596 _ => unreachable!(),
597 }
598 }
599
600 fn move_payload_tail(&mut self, tail: usize, to: usize)
601 where
602 B: crate::buffer::BufferMut,
603 {
604 debug_assert!(is_compact(self));
605 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
606 crate::buffer::UNIT_ID_U8 => {
607 let payload_size = self.payload_size();
608 let buffer = self.buffer_access_mut().specialise_u8_mut();
609 match to.cmp(&tail) {
610 core::cmp::Ordering::Greater => {
611 let d = payload_size.saturating_sub(to);
612 buffer.copy_within(1 + tail..1 + tail + d, to + 1);
613 }
614 core::cmp::Ordering::Less => {
615 buffer.copy_within(1 + tail..1 + payload_size, to + 1);
616 }
617 _ => {}
618 }
619 }
620 crate::buffer::UNIT_ID_U32 => {
621 let payload_size = self.payload_size();
622 let buffer = self.buffer_access_mut().specialise_u32_mut();
623 let index = |payload_index| {
624 let byte_index = payload_index + 2 * (1 + payload_index / 6);
625 (byte_index / 4, byte_index % 4)
626 };
627 match to.cmp(&tail) {
628 core::cmp::Ordering::Greater => {
629 let d = to - tail;
630 for (src, dst) in (tail..(payload_size - d))
631 .rev()
632 .map(|i| (index(i), index(i + d)))
633 {
634 let v = buffer[src.0].octet(src.1);
635 buffer[dst.0].set_octet(dst.1, v);
636 }
637 }
638 core::cmp::Ordering::Less => {
639 let d = tail - to;
640 for (src, dst) in (tail..payload_size).map(|i| (index(i), index(i - d))) {
641 let v = buffer[src.0].octet(src.1);
642 buffer[dst.0].set_octet(dst.1, v);
643 }
644 }
645 _ => {}
646 }
647 }
648 _ => unreachable!(),
649 }
650 }
651
652 fn compact(&mut self)
653 where
654 B: crate::buffer::BufferMut,
655 {
656 if !is_compact(self) {
657 compact(self);
658 }
659 }
660}
661
662fn is_compact<B: crate::buffer::Buffer>(sysex: &Sysex7<B>) -> bool {
663 match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
664 crate::buffer::UNIT_ID_U8 => true,
665 crate::buffer::UNIT_ID_U32 => {
666 use crate::detail::BitOps;
667 for chunk in sysex
668 .0
669 .buffer()
670 .specialise_u32()
671 .chunks_exact(4)
672 .take_while(|packet| u8::from(packet[0].nibble(0)) == UMP_MESSAGE_TYPE)
673 {
674 let status: u8 = chunk[0].nibble(2).into();
675 let is_begin = status == 0x1;
676 let is_continue = status == 0x2;
677 let payload_size_in_packet: u8 = chunk[0].nibble(3).into();
678 if (is_begin || is_continue) && payload_size_in_packet != 6 {
679 return false;
680 }
681 }
682 true
683 }
684 _ => unreachable!(),
685 }
686}
687fn compact<B: crate::buffer::Buffer + crate::buffer::BufferMut>(sysex: &mut Sysex7<B>) {
691 if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
692 return;
693 }
694
695 use crate::{detail::BitOps, BufferAccess};
696
697 let payload_size = sysex.payload_size();
698 let buffer = sysex.buffer_access_mut().specialise_u32_mut();
699 let mut src_packet_index: usize = 0;
700 let mut dst_packet_index = 0;
701 let mut dst_payload_index = 0;
702
703 loop {
705 let status: u8 = buffer[src_packet_index * 2].nibble(2).into();
708
709 if status == 0x0 {
710 break;
711 }
712
713 let size: u8 = buffer[src_packet_index * 2].nibble(3).into();
714
715 for i in 0..size as usize {
716 let v = buffer[src_packet_index * 2 + (i + 2) / 4].octet((i + 2) % 4);
718 buffer[dst_packet_index * 2 + (dst_payload_index + 2) / 4]
719 .set_octet((dst_payload_index + 2) % 4, v);
720 dst_payload_index += 1;
721 if dst_payload_index == 6 {
722 dst_packet_index += 1;
723 dst_payload_index = 0;
724 }
725 }
726
727 src_packet_index += 1;
728
729 if status == 0x3 {
730 break;
731 }
732 }
733
734 try_resize_ump(sysex, payload_size, |_, _| Ok(())).expect("Resizing down should never fail");
736}
737
738fn try_resize_ump<
739 B: crate::buffer::Buffer + crate::buffer::BufferMut,
740 ResizeBuffer: Fn(&mut Sysex7<B>, usize) -> Result<(), crate::error::BufferOverflow>,
741>(
742 sysex: &mut Sysex7<B>,
743 mut payload_size: usize,
744 try_resize_buffer: ResizeBuffer,
745) -> Result<(), crate::traits::SysexTryResizeError> {
746 use ux::u4;
747
748 let mut buffer_size = buffer_size_from_payload_size_ump(payload_size);
749 let resize_result = try_resize_buffer(sysex, buffer_size);
750 if resize_result.is_err() {
751 buffer_size = sysex.0.buffer().len();
752 payload_size = (buffer_size / 2) * 6;
753 }
754
755 let mut iter = sysex
756 .0
757 .specialise_u32_mut()
758 .chunks_exact_mut(2)
759 .take(buffer_size / 2)
760 .peekable();
761 let mut group = None;
762
763 const MESSAGE_TYPE: u4 = u4::new(UMP_MESSAGE_TYPE);
764 const STATUS_COMPLETE: u4 = u4::new(0x0);
765 const STATUS_START: u4 = u4::new(0x1);
766 const STATUS_CONTINUE: u4 = u4::new(0x2);
767 const STATUS_END: u4 = u4::new(0x3);
768
769 if let Some(first_packet) = iter.next() {
771 first_packet[0].set_nibble(0, MESSAGE_TYPE);
772 group = Some(first_packet[0].nibble(1));
773 if iter.peek().is_some() {
774 first_packet[0].set_nibble(2, STATUS_START);
776 first_packet[0].set_nibble(3, u4::new(6));
777 } else {
778 first_packet[0].set_nibble(2, STATUS_COMPLETE);
780 first_packet[0].set_nibble(3, u4::new(payload_size as u8));
781 }
782 }
783
784 while let Some(chunk) = iter.next() {
785 chunk[0].set_nibble(0, MESSAGE_TYPE);
786 chunk[0].set_nibble(1, group.unwrap());
787 if iter.peek().is_some() {
788 chunk[0].set_nibble(2, STATUS_CONTINUE);
790 chunk[0].set_nibble(3, u4::new(6));
791 } else {
792 chunk[0].set_nibble(2, STATUS_END);
794 match payload_size % 6 {
795 0 => {
796 chunk[0].set_nibble(3, u4::new(6));
797 }
798 r => {
799 chunk[0].set_nibble(3, u4::new(r as u8));
800 for i in r..6 {
802 chunk[(i + 2) / 4].set_octet((i + 2) % 4, 0x0);
803 }
804 }
805 };
806 }
807 }
808
809 resize_result.map_err(|_| crate::traits::SysexTryResizeError(payload_size))
810}
811
812fn buffer_size_from_payload_size_ump(payload_size: usize) -> usize {
813 if payload_size.is_multiple_of(6) {
814 if payload_size == 0 {
815 2
816 } else {
817 payload_size / 3
818 }
819 } else {
820 2 * (payload_size / 6 + 1)
821 }
822}
823
824#[derive(Debug, Clone)]
845pub struct PayloadIterator<'a, U: crate::buffer::Unit> {
846 data: &'a [U],
847 payload_index: usize,
848 packet_index: usize,
850 size_cache: usize,
852}
853
854impl<U: crate::buffer::Unit> core::iter::Iterator for PayloadIterator<'_, U> {
855 type Item = ux::u7;
856
857 fn next(&mut self) -> Option<Self::Item> {
858 match U::UNIT_ID {
859 crate::buffer::UNIT_ID_U8 => {
860 let data = <U as crate::buffer::UnitPrivate>::specialise_buffer_u8(self.data);
861 if self.payload_index >= data.len() {
862 None
863 } else {
864 let ret = Some(u7::new(data[self.payload_index]));
865 self.payload_index += 1;
866 ret
867 }
868 }
869 crate::buffer::UNIT_ID_U32 => {
870 if self.finished_ump() {
871 return None;
872 }
873
874 self.skip_empty_packets_ump();
875
876 let ret = Some(self.value_ump());
877 self.advance_ump();
878
879 ret
880 }
881 _ => unreachable!(),
882 }
883 }
884
885 fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
891 match U::UNIT_ID {
892 crate::buffer::UNIT_ID_U8 => {
893 self.payload_index += n;
894 self.next()
895 }
896 crate::buffer::UNIT_ID_U32 => {
897 let mut do_nth = || {
898 let mut packets = self.data_ump()[self.packet_index * 2..]
899 .chunks_exact(2)
900 .enumerate();
901
902 {
903 let remaining = Self::packet_size(packets.next()?.1) - self.payload_index;
906 if n < remaining {
907 self.payload_index += n;
908 self.size_cache -= n;
909 return self.next();
910 } else {
911 n -= remaining;
912 self.size_cache -= remaining;
913 }
914 }
915
916 loop {
919 let (packet_index, packet) = packets.next()?;
920 let size = Self::packet_size(packet);
921 if n < size {
922 self.packet_index += packet_index;
924 self.payload_index = n;
925 self.size_cache -= n;
926 break;
927 }
928 n -= size;
929 self.size_cache -= size;
930 }
931
932 self.next()
933 };
934
935 let ret = do_nth();
936 if ret.is_none() {
937 self.packet_index = self.data.len() / 2;
940 self.size_cache = 0;
941 }
942 ret
943 }
944 _ => unreachable!(),
945 }
946 }
947
948 fn count(self) -> usize
949 where
950 Self: Sized,
951 {
952 self.len()
953 }
954
955 fn size_hint(&self) -> (usize, Option<usize>) {
956 (self.size_cache, Some(self.size_cache))
957 }
958}
959
960impl<'a, U: crate::buffer::Unit> PayloadIterator<'a, U> {
961 fn data_ump(&self) -> &'a [u32] {
962 <U as crate::buffer::UnitPrivate>::specialise_buffer_u32(self.data)
963 }
964
965 fn value_ump(&self) -> ux::u7 {
966 let buffer_index = self.packet_index * 2 + (self.payload_index + 2) / 4;
967 let octet_index = (self.payload_index + 2) % 4;
968 self.data_ump()[buffer_index].septet(octet_index)
969 }
970
971 fn finished_ump(&self) -> bool {
972 self.size_cache == 0
973 }
974
975 fn skip_empty_packets_ump(&mut self) {
976 while !self.finished_ump() && self.current_packet_size_ump() == 0 {
977 self.payload_index = 0;
978 self.packet_index += 1;
979 }
980 }
981
982 fn advance_ump(&mut self) {
983 self.payload_index += 1;
984 if !self.finished_ump() {
985 self.size_cache -= 1;
986 }
987
988 if self.payload_index == self.current_packet_size_ump() {
989 self.packet_index += 1;
991 self.payload_index = 0;
992 }
993
994 self.skip_empty_packets_ump();
995 }
996
997 fn current_packet_size_ump(&self) -> usize {
998 Self::packet_size(&self.data_ump()[self.packet_index * 2..self.packet_index * 2 + 2])
999 }
1000
1001 fn packet_size(packet: &[u32]) -> usize {
1002 u8::from(packet[0].nibble(3)) as usize
1003 }
1004}
1005
1006impl<U: crate::buffer::Unit> core::iter::FusedIterator for PayloadIterator<'_, U> {}
1007
1008impl<U: crate::buffer::Unit> core::iter::ExactSizeIterator for PayloadIterator<'_, U> {
1009 fn len(&self) -> usize {
1010 match U::UNIT_ID {
1011 crate::buffer::UNIT_ID_U8 => self.data[self.payload_index..].len(),
1012 crate::buffer::UNIT_ID_U32 => self.size_cache,
1013 _ => unreachable!(),
1014 }
1015 }
1016}
1017
1018#[cfg(test)]
1019mod tests {
1020 use super::*;
1021 use crate::{
1022 traits::{FromBytes, FromUmp, Grouped, RebufferInto, Sysex},
1023 ux::*,
1024 };
1025 use pretty_assertions::assert_eq;
1026
1027 #[test]
1028 fn new_bytes() {
1029 let message = Sysex7::<std::vec::Vec<u8>>::new();
1030 assert_eq!(message, Sysex7(std::vec![0xF0, 0xF7]));
1031 }
1032
1033 #[test]
1034 fn bytes_try_new_with_buffer() {
1035 let mut buffer = [0x0_u8; 50];
1036 let message = Sysex7::try_new_with_buffer(&mut buffer[..]);
1037 assert_eq!(message.unwrap().data(), &[0xF0, 0xF7][..]);
1038 }
1039
1040 #[test]
1041 fn bytes_try_new_with_buffer_write_payload_data() {
1042 let mut buffer = [0x0_u8; 50];
1043 let mut message = Sysex7::try_new_with_buffer(&mut buffer[..]).unwrap();
1044 message.try_set_payload((0..10).map(u7::new)).unwrap();
1045 assert_eq!(
1046 message.data(),
1047 &[0xF0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xF7][..]
1048 );
1049 }
1050
1051 #[test]
1052 fn try_new_bytes() {
1053 let message = Sysex7::<[u8; 2]>::try_new().expect("Buffer is large enough");
1054 assert_eq!(message, Sysex7([0xF0, 0xF7]));
1055 }
1056
1057 #[test]
1058 fn data_bytes() {
1059 let message = Sysex7::<std::vec::Vec<u8>>::new();
1060 assert_eq!(message.data(), &[0xF0, 0xF7]);
1061 }
1062
1063 #[test]
1064 fn try_from_bytes() {
1065 assert_eq!(
1066 Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7_u8][..]),
1067 Ok(Sysex7(&[0xF0, 0x0, 0x1, 0x2, 0xF7][..])),
1068 )
1069 }
1070
1071 #[test]
1072 fn try_from_oversized_bytes() {
1073 assert_eq!(
1074 Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7, 0x0][..]),
1075 Ok(Sysex7(&[0xF0, 0x0, 0x1, 0x2, 0xF7, 0x0][..])),
1076 )
1077 }
1078
1079 #[test]
1080 fn data_oversized_bytes() {
1081 assert_eq!(
1082 Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7, 0x0][..])
1083 .unwrap()
1084 .data(),
1085 &[0xF0, 0x0, 0x1, 0x2, 0xF7],
1086 );
1087 }
1088
1089 #[test]
1090 fn try_from_bytes_with_no_end_byte() {
1091 assert_eq!(
1092 Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8][..]),
1093 Err(crate::error::InvalidData(ERR_NO_END_BYTE))
1094 )
1095 }
1096
1097 #[test]
1098 fn try_from_bytes_with_no_begin_byte() {
1099 assert_eq!(
1100 Sysex7::try_from(&[0x0_u8, 0x1_u8, 0x2_u8, 0xF7_u8][..]),
1101 Err(crate::error::InvalidData(ERR_NO_BEGIN_BYTE))
1102 )
1103 }
1104
1105 #[test]
1106 fn new_ump() {
1107 let message = Sysex7::<std::vec::Vec<u32>>::new();
1108 assert_eq!(message, Sysex7(std::vec![0x3000_0000, 0x0000_0000,]));
1109 }
1110
1111 #[test]
1112 fn data_ump() {
1113 let message = Sysex7::<std::vec::Vec<u32>>::new();
1114 assert_eq!(message.data(), &[0x3000_0000, 0x0000_0000,]);
1115 }
1116
1117 #[test]
1118 fn try_from_ump() {
1119 assert_eq!(
1120 Sysex7::try_from(
1121 &[
1122 0x3416_0001_u32,
1123 0x0203_0405_u32,
1124 0x3426_0607_u32,
1125 0x0809_0A0B_u32,
1126 0x3433_0C0D_u32,
1127 0x0E00_0000_u32,
1128 ][..]
1129 ),
1130 Ok(Sysex7(
1131 &[
1132 0x3416_0001_u32,
1133 0x0203_0405_u32,
1134 0x3426_0607_u32,
1135 0x0809_0A0B_u32,
1136 0x3433_0C0D_u32,
1137 0x0E00_0000_u32,
1138 ][..]
1139 ))
1140 );
1141 }
1142
1143 #[test]
1144 fn set_group_ump() {
1145 let mut message: Sysex7<std::vec::Vec<u32>> = Sysex7::try_from(
1146 &[
1147 0x3416_0001_u32,
1148 0x0203_0405_u32,
1149 0x3426_0607_u32,
1150 0x0809_0A0B_u32,
1151 0x3433_0C0D_u32,
1152 0x0E00_0000_u32,
1153 ][..],
1154 )
1155 .unwrap()
1156 .rebuffer_into();
1157 message.set_group(u4::new(0x5));
1158 assert_eq!(
1159 message,
1160 Sysex7(std::vec![
1161 0x3516_0001_u32,
1162 0x0203_0405_u32,
1163 0x3526_0607_u32,
1164 0x0809_0A0B_u32,
1165 0x3533_0C0D_u32,
1166 0x0E00_0000_u32,
1167 ])
1168 );
1169 }
1170
1171 #[test]
1172 fn try_from_oversized_ump() {
1173 assert_eq!(
1174 Sysex7::try_from(
1175 &[
1176 0x3416_0001_u32,
1177 0x0203_0405_u32,
1178 0x3426_0607_u32,
1179 0x0809_0A0B_u32,
1180 0x3433_0C0D_u32,
1181 0x0E00_0000_u32,
1182 0x0000_0000_u32,
1183 0x0000_0000_u32,
1184 ][..]
1185 ),
1186 Ok(Sysex7(
1187 &[
1188 0x3416_0001_u32,
1189 0x0203_0405_u32,
1190 0x3426_0607_u32,
1191 0x0809_0A0B_u32,
1192 0x3433_0C0D_u32,
1193 0x0E00_0000_u32,
1194 0x0000_0000_u32,
1195 0x0000_0000_u32,
1196 ][..]
1197 ))
1198 );
1199 }
1200
1201 #[test]
1202 fn data_oversized_ump() {
1203 assert_eq!(
1204 Sysex7::try_from(
1205 &[
1206 0x3416_0001_u32,
1207 0x0203_0405_u32,
1208 0x3426_0607_u32,
1209 0x0809_0A0B_u32,
1210 0x3433_0C0D_u32,
1211 0x0E00_0000_u32,
1212 0x0000_0000_u32,
1213 0x0000_0000_u32,
1214 ][..]
1215 )
1216 .unwrap()
1217 .data(),
1218 &[
1219 0x3416_0001,
1220 0x0203_0405,
1221 0x3426_0607,
1222 0x0809_0A0B,
1223 0x3433_0C0D,
1224 0x0E00_0000,
1225 ],
1226 );
1227 }
1228
1229 #[test]
1230 fn data_odd_sized_buffer_ump() {
1231 assert_eq!(
1232 Sysex7::try_from(
1233 &[
1234 0x3416_0001_u32,
1235 0x0203_0405_u32,
1236 0x3426_0607_u32,
1237 0x0809_0A0B_u32,
1238 0x3433_0C0D_u32,
1239 0x0E00_0000_u32,
1240 0x0000_0000_u32,
1241 ][..]
1242 )
1243 .unwrap()
1244 .data(),
1245 &[
1246 0x3416_0001,
1247 0x0203_0405,
1248 0x3426_0607,
1249 0x0809_0A0B,
1250 0x3433_0C0D,
1251 0x0E00_0000,
1252 ],
1253 );
1254 }
1255
1256 #[test]
1257 fn try_from_ump_inconsistent_groups() {
1258 assert_eq!(
1259 Sysex7::try_from(
1260 &[
1261 0x3416_0001_u32,
1262 0x0203_0405_u32,
1263 0x3326_0607_u32,
1264 0x0809_0A0B_u32,
1265 0x3433_0C0D_u32,
1266 0x0E00_0000_u32,
1267 ][..]
1268 ),
1269 Err(crate::error::InvalidData(
1270 message_helpers::ERR_INCONSISTENT_GROUPS
1271 )),
1272 );
1273 }
1274
1275 #[test]
1276 fn try_from_ump_incorrect_end_status() {
1277 assert_eq!(
1278 Sysex7::try_from(
1279 &[
1280 0x3416_0001_u32,
1281 0x0203_0405_u32,
1282 0x3426_0607_u32,
1283 0x0809_0A0B_u32,
1284 0x3403_0C0D_u32,
1285 0x0E00_0000_u32,
1286 ][..]
1287 ),
1288 Err(crate::error::InvalidData(
1289 message_helpers::ERR_SYSEX_EXPECTED_END
1290 )),
1291 );
1292 }
1293
1294 #[test]
1295 fn try_from_ump_incorrect_complete_status() {
1296 assert_eq!(
1297 Sysex7::try_from(&[0x3416_0001_u32, 0x0203_0405_u32,][..]),
1298 Err(crate::error::InvalidData(
1299 message_helpers::ERR_SYSEX_EXPECTED_COMPLETE
1300 )),
1301 );
1302 }
1303
1304 #[test]
1305 fn try_from_ump_incorrect_begin_status() {
1306 assert_eq!(
1307 Sysex7::try_from(
1308 &[
1309 0x3406_0001_u32,
1310 0x0203_0405_u32,
1311 0x3426_0607_u32,
1312 0x0809_0A0B_u32,
1313 0x3433_0C0D_u32,
1314 0x0E00_0000_u32,
1315 ][..]
1316 ),
1317 Err(crate::error::InvalidData(
1318 message_helpers::ERR_SYSEX_EXPECTED_BEGIN
1319 )),
1320 );
1321 }
1322
1323 #[test]
1324 fn try_from_ump_incorrect_continue_status() {
1325 assert_eq!(
1326 Sysex7::try_from(
1327 &[
1328 0x3416_0001_u32,
1329 0x0203_0405_u32,
1330 0x3456_0607_u32,
1331 0x0809_0A0B_u32,
1332 0x3433_0C0D_u32,
1333 0x0E00_0000_u32,
1334 ][..]
1335 ),
1336 Err(crate::error::InvalidData(
1337 message_helpers::ERR_SYSEX_EXPECTED_CONTINUE
1338 )),
1339 );
1340 }
1341
1342 #[test]
1343 fn try_from_ump_invalid_packet_sizes() {
1344 assert_eq!(
1345 Sysex7::try_from(
1346 &[
1347 0x3416_0001_u32,
1348 0x0203_0405_u32,
1349 0x3427_0607_u32,
1350 0x0809_0A0B_u32,
1351 0x3433_0C0D_u32,
1352 0x0E00_0000_u32,
1353 ][..]
1354 ),
1355 Err(crate::error::InvalidData(ERR_INVALID_PACKET_SIZE)),
1356 );
1357 }
1358
1359 #[test]
1360 fn set_payload_bytes() {
1361 let mut message = Sysex7::<std::vec::Vec<u8>>::new();
1362 message.set_payload((0u8..20u8).map(u7::new));
1363 assert_eq!(
1364 message,
1365 Sysex7(std::vec![
1366 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1367 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xF7,
1368 ])
1369 );
1370 }
1371
1372 #[test]
1373 fn try_set_payload_bytes() {
1374 let mut message = Sysex7::<[u8; 22]>::new();
1375 message.try_set_payload((0u8..20u8).map(u7::new)).unwrap();
1376 assert_eq!(
1377 message,
1378 Sysex7([
1379 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1380 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xF7,
1381 ])
1382 );
1383 }
1384
1385 #[test]
1386 fn try_set_payload_bytes_fail() {
1387 let mut message = Sysex7::<[u8; 22]>::new();
1388 assert_eq!(
1389 message.try_set_payload((0u8..30u8).map(u7::new)),
1390 Err(crate::error::BufferOverflow),
1391 );
1392 }
1393
1394 #[test]
1395 fn set_payload_ump() {
1396 let mut message = Sysex7::<std::vec::Vec<u32>>::new();
1397 message.set_payload((0u8..30u8).map(u7::new));
1398 assert_eq!(
1399 message,
1400 Sysex7(std::vec![
1401 0x3016_0001,
1402 0x0203_0405,
1403 0x3026_0607,
1404 0x0809_0A0B,
1405 0x3026_0C0D,
1406 0x0E0F_1011,
1407 0x3026_1213,
1408 0x1415_1617,
1409 0x3036_1819,
1410 0x1A1B_1C1D,
1411 ])
1412 );
1413 }
1414
1415 #[test]
1416 fn set_rubbish_payload_ump() {
1417 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
1418 let mut message = Sysex7::<std::vec::Vec<u32>>::new();
1419 message.set_payload(RubbishPayloadIterator::new().map(u7::new));
1420 assert_eq!(
1421 message,
1422 Sysex7(std::vec![
1423 0x3016_0001,
1424 0x0203_0405,
1425 0x3026_0607,
1426 0x0809_0A0B,
1427 0x3026_0C0D,
1428 0x0E0F_1011,
1429 0x3026_1213,
1430 0x1415_1617,
1431 0x3026_1819,
1432 0x1A1B_1C1D,
1433 0x3026_1E1F,
1434 0x2021_2223,
1435 0x3026_2425,
1436 0x2627_2829,
1437 0x3026_2A2B,
1438 0x2C2D_2E2F,
1439 0x3032_3031,
1440 0x0000_0000,
1441 ])
1442 );
1443 }
1444
1445 #[test]
1446 fn try_set_rubbish_payload_to_fixed_size_buffer_ump() {
1447 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
1448 let mut message = Sysex7::<[u32; 18]>::new();
1449 message
1450 .try_set_payload(RubbishPayloadIterator::new().map(u7::new))
1451 .expect("Shouldn't fail");
1452 assert_eq!(
1453 message,
1454 Sysex7([
1455 0x3016_0001,
1456 0x0203_0405,
1457 0x3026_0607,
1458 0x0809_0A0B,
1459 0x3026_0C0D,
1460 0x0E0F_1011,
1461 0x3026_1213,
1462 0x1415_1617,
1463 0x3026_1819,
1464 0x1A1B_1C1D,
1465 0x3026_1E1F,
1466 0x2021_2223,
1467 0x3026_2425,
1468 0x2627_2829,
1469 0x3026_2A2B,
1470 0x2C2D_2E2F,
1471 0x3032_3031,
1472 0x0000_0000,
1473 ])
1474 );
1475 }
1476
1477 #[test]
1478 fn reset_smaller_payload_bytes() {
1479 let mut message = Sysex7::<std::vec::Vec<u8>>::new();
1480 message.set_payload((0u8..20u8).map(u7::new));
1481 message.set_payload((0u8..10).map(u7::new));
1482 assert_eq!(
1483 message,
1484 Sysex7(std::vec![
1485 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xF7,
1486 ])
1487 );
1488 }
1489
1490 #[test]
1491 fn reset_larger_payload_bytes() {
1492 let mut message = Sysex7::<std::vec::Vec<u8>>::new();
1493 message.set_payload((0u8..20u8).map(u7::new));
1494 message.set_payload((0u8..30).map(u7::new));
1495 assert_eq!(
1496 message,
1497 Sysex7(std::vec![
1498 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1499 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1500 0x1B, 0x1C, 0x1D, 0xF7,
1501 ])
1502 );
1503 }
1504
1505 #[test]
1506 fn set_rubbish_payload_bytes() {
1507 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
1508 let mut message = Sysex7::<std::vec::Vec<u8>>::new();
1509 message.set_payload(RubbishPayloadIterator::new().map(u7::new));
1510 assert_eq!(
1511 message,
1512 Sysex7(std::vec![
1513 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1514 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1515 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
1516 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0xF7,
1517 ])
1518 );
1519 }
1520
1521 #[test]
1522 fn try_set_rubbish_payload_to_fixed_size_buffer() {
1523 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
1524 let mut message = Sysex7::<[u8; 52]>::new();
1525 message
1526 .try_set_payload(RubbishPayloadIterator::new().map(u7::new))
1527 .expect("Shouldn't fail");
1528 assert_eq!(
1529 message,
1530 Sysex7([
1531 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1532 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1533 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
1534 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0xF7,
1535 ])
1536 );
1537 }
1538
1539 #[test]
1540 fn payload_bytes() {
1541 assert_eq!(
1542 std::vec![
1543 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
1544 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
1545 0x1C, 0x1D,
1546 ],
1547 Sysex7::try_from(
1548 &[
1549 0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
1550 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1551 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0xF7,
1552 ][..]
1553 )
1554 .unwrap()
1555 .payload()
1556 .map(u8::from)
1557 .collect::<std::vec::Vec<u8>>()
1558 );
1559 }
1560
1561 #[test]
1562 #[allow(clippy::iter_nth_zero)]
1563 fn payload_bytes_nth() {
1564 let buffer = [
1565 0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1566 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1567 0x1B, 0x1C, 0x1D, 0xF7,
1568 ];
1569 let message = Sysex7::try_from(&buffer[..]).unwrap();
1570 let mut payload = message.payload();
1571 assert_eq!(payload.nth(0), Some(u7::new(0x0)));
1572 assert_eq!(payload.nth(4), Some(u7::new(0x5)));
1573 assert_eq!(payload.nth(12), Some(u7::new(0x12)));
1574 assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
1575 assert_eq!(payload.nth(0), None);
1576 }
1577
1578 #[test]
1579 fn payload_bytes_nth_with_empty_packets() {
1580 let buffer = [
1581 0x3010_0000_u32,
1582 0x0000_0000,
1583 0x3021_0000,
1584 0x0000_0000,
1585 0x3022_0102,
1586 0x0000_0000,
1587 0x3020_0000,
1588 0x0000_0000,
1589 0x3020_0000,
1590 0x0000_0000,
1591 0x3023_0304,
1592 0x0500_0000,
1593 0x3024_0607,
1594 0x0809_0000,
1595 0x3025_0A0B,
1596 0x0C0D_0E00,
1597 0x3026_0F10,
1598 0x1112_1314,
1599 0x3025_1516,
1600 0x1718_1900,
1601 0x3034_1A1B,
1602 0x1C1D_0000,
1603 0x0000_0000,
1604 0x0000_0000,
1605 0x0000_0000,
1606 0x0000_0000,
1607 0x0000_0000,
1608 ];
1609 let message = Sysex7::try_from(&buffer[..]).unwrap();
1610 let mut payload = message.payload();
1611 assert_eq!(payload.len(), 30);
1612 assert_eq!(payload.next(), Some(u7::new(0x0)));
1613 assert_eq!(payload.len(), 29);
1614 assert_eq!(payload.nth(4), Some(u7::new(0x5)));
1615 assert_eq!(payload.len(), 24);
1616 assert_eq!(payload.nth(12), Some(u7::new(0x12)));
1617 assert_eq!(payload.len(), 11);
1618 assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
1619 assert_eq!(payload.len(), 0);
1620 assert_eq!(payload.next(), None);
1621 assert_eq!(payload.len(), 0);
1622 }
1623
1624 #[test]
1625 fn payload_bytes_len() {
1626 assert_eq!(
1627 Sysex7::try_from(
1628 &[
1629 0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
1630 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1631 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0xF7,
1632 ][..]
1633 )
1634 .unwrap()
1635 .payload()
1636 .len(),
1637 30,
1638 );
1639 }
1640
1641 #[test]
1642 fn payload_ump() {
1643 assert_eq!(
1644 Sysex7::try_from(
1645 &[
1646 0x3016_0001_u32,
1647 0x0203_0405,
1648 0x3026_0607,
1649 0x0809_0A0B,
1650 0x3026_0C0D,
1651 0x0E0F_1011,
1652 0x3026_1213,
1653 0x1415_1617,
1654 0x3036_1819,
1655 0x1A1B_1C1D,
1656 ][..]
1657 )
1658 .unwrap()
1659 .payload()
1660 .map(u8::from)
1661 .collect::<std::vec::Vec<u8>>(),
1662 std::vec![
1663 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
1664 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
1665 0x1C, 0x1D,
1666 ],
1667 );
1668 }
1669
1670 #[test]
1671 #[allow(clippy::iter_nth_zero)]
1672 fn payload_ump_nth() {
1673 let buffer = [
1674 0x3016_0001_u32,
1675 0x0203_0405,
1676 0x3026_0607,
1677 0x0809_0A0B,
1678 0x3026_0C0D,
1679 0x0E0F_1011,
1680 0x3026_1213,
1681 0x1415_1617,
1682 0x3036_1819,
1683 0x1A1B_1C1D,
1684 ];
1685 let message = Sysex7::try_from(&buffer[..]).unwrap();
1686 let mut payload = message.payload();
1687 assert_eq!(payload.len(), 30);
1688 assert_eq!(payload.nth(0), Some(u7::new(0x0)));
1689 assert_eq!(payload.len(), 29);
1690 assert_eq!(payload.nth(4), Some(u7::new(0x5)));
1691 assert_eq!(payload.len(), 24);
1692 assert_eq!(payload.nth(12), Some(u7::new(0x12)));
1693 assert_eq!(payload.len(), 11);
1694 assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
1695 assert_eq!(payload.len(), 0);
1696 assert_eq!(payload.nth(0), None);
1697 assert_eq!(payload.len(), 0);
1698 }
1699
1700 #[test]
1701 #[allow(clippy::iter_nth_zero)]
1702 fn payload_ump_nth_non_contiguous_oversized() {
1703 let buffer = [
1704 0x3010_0000_u32,
1705 0x0000_0000,
1706 0x3021_0000,
1707 0x0000_0000,
1708 0x3022_0102,
1709 0x0000_0000,
1710 0x3023_0304,
1711 0x0500_0000,
1712 0x3024_0607,
1713 0x0809_0000,
1714 0x3025_0A0B,
1715 0x0C0D_0E00,
1716 0x3026_0F10,
1717 0x1112_1314,
1718 0x3025_1516,
1719 0x1718_1900,
1720 0x3034_1A1B,
1721 0x1C1D_0000,
1722 0x0000_0000,
1723 0x0000_0000,
1724 0x0000_0000,
1725 0x0000_0000,
1726 0x0000_0000,
1727 ];
1728 let message = Sysex7::try_from(&buffer[..]).unwrap();
1729 let mut payload = message.payload();
1730 assert_eq!(payload.len(), 30);
1731 assert_eq!(payload.nth(0), Some(u7::new(0x0)));
1732 assert_eq!(payload.len(), 29);
1733 assert_eq!(payload.nth(4), Some(u7::new(0x5)));
1734 assert_eq!(payload.len(), 24);
1735 assert_eq!(payload.nth(12), Some(u7::new(0x12)));
1736 assert_eq!(payload.len(), 11);
1737 assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
1738 assert_eq!(payload.len(), 0);
1739 assert_eq!(payload.nth(0), None);
1740 assert_eq!(payload.len(), 0);
1741 }
1742
1743 #[test]
1744 fn from_bytes() {
1745 let buffer = [
1746 0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1747 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1748 0x1B, 0x1C, 0x1D, 0xF7,
1749 ];
1750 let message = Sysex7::try_from(&buffer[..]).unwrap();
1751 assert_eq!(
1752 Sysex7::<std::vec::Vec<u32>>::from_bytes(message),
1753 Sysex7(std::vec![
1754 0x3016_0001,
1755 0x0203_0405,
1756 0x3026_0607,
1757 0x0809_0A0B,
1758 0x3026_0C0D,
1759 0x0E0F_1011,
1760 0x3026_1213,
1761 0x1415_1617,
1762 0x3036_1819,
1763 0x1A1B_1C1D,
1764 ])
1765 );
1766 }
1767
1768 #[test]
1769 fn from_ump() {
1770 let buffer = [
1771 0x3016_0001_u32,
1772 0x0203_0405,
1773 0x3026_0607,
1774 0x0809_0A0B,
1775 0x3026_0C0D,
1776 0x0E0F_1011,
1777 0x3026_1213,
1778 0x1415_1617,
1779 0x3036_1819,
1780 0x1A1B_1C1D,
1781 ];
1782 let message = Sysex7::try_from(&buffer[..]).unwrap();
1783 assert_eq!(
1784 Sysex7::<std::vec::Vec<u8>>::from_ump(message),
1785 Sysex7(std::vec![
1786 0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
1787 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
1788 0x1B, 0x1C, 0x1D, 0xF7,
1789 ])
1790 );
1791 }
1792
1793 #[test]
1794 fn set_payload_to_fixed_size_buffer_with_overflow() {
1795 let mut message = Sysex7::<[u32; 8]>::new();
1796 assert_eq!(
1797 message.try_set_payload((0..30).map(u7::new)),
1798 Err(crate::error::BufferOverflow)
1799 );
1800 }
1801
1802 #[test]
1803 fn empty_payload_ump() {
1804 assert_eq!(
1805 Sysex7::<std::vec::Vec<u32>>::new()
1806 .payload()
1807 .collect::<std::vec::Vec<u7>>(),
1808 std::vec![]
1809 );
1810 }
1811
1812 #[test]
1813 fn packets() {
1814 use crate::Packets;
1815
1816 let buffer = [
1817 0x3016_0001_u32,
1818 0x0203_0405,
1819 0x3026_0607,
1820 0x0809_0A0B,
1821 0x3026_0C0D,
1822 0x0E0F_1011,
1823 0x3026_1213,
1824 0x1415_1617,
1825 0x3036_1819,
1826 0x1A1B_1C1D,
1827 ];
1828 let message = Sysex7::try_from(&buffer[..]).unwrap();
1829 let mut packets = message.packets();
1830
1831 assert_eq!(&*packets.next().unwrap(), &[0x3016_0001, 0x0203_0405,][..]);
1832 assert_eq!(&*packets.next().unwrap(), &[0x3026_0607, 0x0809_0A0B,][..]);
1833 assert_eq!(&*packets.next().unwrap(), &[0x3026_0C0D, 0x0E0F_1011,][..]);
1834 assert_eq!(&*packets.next().unwrap(), &[0x3026_1213, 0x1415_1617,][..]);
1835 assert_eq!(&*packets.next().unwrap(), &[0x3036_1819, 0x1A1B_1C1D,][..]);
1836 assert_eq!(packets.next(), None);
1837 }
1838
1839 #[test]
1840 fn packets_empty() {
1841 use crate::Packets;
1842
1843 let message = Sysex7::<[u32; 2]>::new();
1844 let mut packets = message.packets();
1845
1846 assert_eq!(&*packets.next().unwrap(), &[0x3000_0000, 0x0][..]);
1847 assert_eq!(packets.next(), None);
1848 }
1849
1850 #[test]
1851 fn empty_message_is_compact() {
1852 assert!(is_compact(&Sysex7(std::vec![0x3000_0000_u32, 0x0000_0000])));
1853 }
1854
1855 #[test]
1856 fn message_with_two_empty_packets_is_not_compact() {
1857 assert!(!is_compact(&Sysex7(std::vec![
1858 0x3010_0000_u32,
1859 0x0000_0000,
1860 0x3030_0000,
1861 0x0000_0000,
1862 ])));
1863 }
1864
1865 #[test]
1866 fn message_with_non_contiguous_payload_is_not_compact() {
1867 assert!(!is_compact(&Sysex7(std::vec![
1868 0x3010_0000_u32,
1869 0x0000_0000,
1870 0x3021_0000,
1871 0x0000_0000,
1872 0x3022_0102,
1873 0x0000_0000,
1874 0x3023_0304,
1875 0x0500_0000,
1876 0x3024_0607,
1877 0x0809_0000,
1878 0x3025_0A0B,
1879 0x0C0D_0E00,
1880 0x3026_0F10,
1881 0x1112_1314,
1882 0x3025_1516,
1883 0x1718_1900,
1884 0x3034_1A1B,
1885 0x1C1D_0000,
1886 0x0000_0000,
1887 0x0000_0000,
1888 0x0000_0000,
1889 0x0000_0000,
1890 0x0000_0000,
1891 ])));
1892 }
1893
1894 #[test]
1895 fn message_with_empty_packets_is_not_compact() {
1896 assert!(!is_compact(&Sysex7(std::vec![
1897 0x3010_0000_u32,
1898 0x0000_0000,
1899 0x3021_0000,
1900 0x0000_0000,
1901 0x3022_0102,
1902 0x0000_0000,
1903 0x3020_0000,
1904 0x0000_0000,
1905 0x3020_0000,
1906 0x0000_0000,
1907 0x3023_0304,
1908 0x0500_0000,
1909 0x3024_0607,
1910 0x0809_0000,
1911 0x3025_0A0B,
1912 0x0C0D_0E00,
1913 0x3026_0F10,
1914 0x1112_1314,
1915 0x3025_1516,
1916 0x1718_1900,
1917 0x3034_1A1B,
1918 0x1C1D_0000,
1919 0x0000_0000,
1920 0x0000_0000,
1921 0x0000_0000,
1922 0x0000_0000,
1923 0x0000_0000,
1924 ])))
1925 }
1926
1927 #[test]
1928 fn large_message_with_contiguous_payload_is_compact() {
1929 assert!(is_compact(&Sysex7(std::vec![
1930 0x3016_0001_u32,
1931 0x0203_0405,
1932 0x3026_0607,
1933 0x0809_0A0B,
1934 0x3026_0C0D,
1935 0x0E0F_1011,
1936 0x3026_1213,
1937 0x1415_1617,
1938 0x3026_1819,
1939 0x1A1B_1C1D,
1940 0x3026_1E1F,
1941 0x2021_2223,
1942 0x3026_2425,
1943 0x2627_2829,
1944 0x3026_2A2B,
1945 0x2C2D_2E2F,
1946 0x3032_3031,
1947 0x0000_0000,
1948 ])));
1949 }
1950
1951 #[test]
1952 fn compact_a_complete_message_is_no_op() {
1953 let mut message = Sysex7([0x3005_0102_u32, 0x0304_0500]);
1954 compact(&mut message);
1955 assert_eq!(message.data(), &[0x3005_0102_u32, 0x0304_0500,])
1956 }
1957
1958 #[test]
1959 fn message_of_two_empty_packets_compacts_down_to_one_empty_packet() {
1960 let mut message = Sysex7([0x3010_0000_u32, 0x0000_0000, 0x3030_0000, 0x0000_0000]);
1961 compact(&mut message);
1962 assert_eq!(message.data(), &[0x3000_0000, 0x0000_0000]);
1963 }
1964
1965 #[test]
1966 fn message_with_non_contiguous_payload_compacts_down() {
1967 let mut message = Sysex7(std::vec![
1968 0x3010_0000_u32,
1969 0x0000_0000,
1970 0x3021_0000,
1971 0x0000_0000,
1972 0x3022_0102,
1973 0x0000_0000,
1974 0x3023_0304,
1975 0x0500_0000,
1976 0x3024_0607,
1977 0x0809_0000,
1978 0x3025_0A0B,
1979 0x0C0D_0E00,
1980 0x3026_0F10,
1981 0x1112_1314,
1982 0x3025_1516,
1983 0x1718_1900,
1984 0x3024_1A1B,
1985 0x1C1D_0000,
1986 0x3023_1E1F,
1987 0x2000_0000,
1988 0x3022_2122,
1989 0x0000_0000,
1990 0x3021_2300,
1991 0x0000_0000,
1992 0x3020_0000,
1993 0x0000_0000,
1994 0x3021_2400,
1995 0x0000_0000,
1996 0x3022_2526,
1997 0x0000_0000,
1998 0x3023_2728,
1999 0x2900_0000,
2000 0x3024_2A2B,
2001 0x2C2D_0000,
2002 0x3034_2E2F,
2003 0x3031_0000,
2004 ]);
2005 compact(&mut message);
2006 assert_eq!(
2007 message.data(),
2008 &[
2009 0x3016_0001,
2010 0x0203_0405,
2011 0x3026_0607,
2012 0x0809_0A0B,
2013 0x3026_0C0D,
2014 0x0E0F_1011,
2015 0x3026_1213,
2016 0x1415_1617,
2017 0x3026_1819,
2018 0x1A1B_1C1D,
2019 0x3026_1E1F,
2020 0x2021_2223,
2021 0x3026_2425,
2022 0x2627_2829,
2023 0x3026_2A2B,
2024 0x2C2D_2E2F,
2025 0x3032_3031,
2026 0x0000_0000,
2027 ]
2028 );
2029 }
2030
2031 fn move_payload_tail_no_op<U: crate::buffer::Unit>() {
2032 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2033 message.set_payload((0u8..30u8).map(u7::new));
2034 message.move_payload_tail(0, 0);
2035 assert_eq!(
2036 message.payload().collect::<std::vec::Vec<u7>>(),
2037 (0u8..30u8).map(u7::new).collect::<std::vec::Vec<u7>>()
2038 );
2039 }
2040
2041 #[test]
2042 fn move_payload_tail_ump_no_op() {
2043 move_payload_tail_no_op::<u32>();
2044 }
2045
2046 #[test]
2047 fn move_payload_tail_bytes_no_op() {
2048 move_payload_tail_no_op::<u8>();
2049 }
2050
2051 fn move_payload_tail_one_place<U: crate::buffer::Unit>() {
2052 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2053 message.set_payload((0u8..30u8).map(u7::new));
2054 message.move_payload_tail(0, 1);
2055 assert_eq!(
2056 message.payload().collect::<std::vec::Vec<u7>>(),
2057 [
2058 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
2059 22, 23, 24, 25, 26, 27, 28,
2060 ]
2061 .iter()
2062 .cloned()
2063 .map(ux::u7::new)
2064 .collect::<std::vec::Vec<u7>>()
2065 );
2066 }
2067
2068 #[test]
2069 fn move_payload_tail_ump_one_place() {
2070 move_payload_tail_one_place::<u32>();
2071 }
2072
2073 #[test]
2074 fn move_payload_tail_bytes_one_place() {
2075 move_payload_tail_one_place::<u8>();
2076 }
2077
2078 fn move_payload_tail_ten_places<U: crate::buffer::Unit>() {
2079 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2080 message.set_payload((0u8..30u8).map(u7::new));
2081 message.move_payload_tail(0, 10);
2082 assert_eq!(
2083 message.payload().collect::<std::vec::Vec<u7>>(),
2084 [
2085 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2086 16, 17, 18, 19,
2087 ]
2088 .iter()
2089 .cloned()
2090 .map(ux::u7::new)
2091 .collect::<std::vec::Vec<u7>>()
2092 );
2093 }
2094
2095 #[test]
2096 fn move_payload_tail_ump_ten_places() {
2097 move_payload_tail_ten_places::<u32>();
2098 }
2099
2100 #[test]
2101 fn move_payload_tail_bytes_ten_places() {
2102 move_payload_tail_ten_places::<u8>();
2103 }
2104
2105 fn move_payload_tail_ten_places_back<U: crate::buffer::Unit>() {
2106 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2107 message.set_payload((0u8..30u8).map(u7::new));
2108 message.move_payload_tail(10, 0);
2109 assert_eq!(
2110 message.payload().collect::<std::vec::Vec<u7>>(),
2111 [
2112 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 20,
2113 21, 22, 23, 24, 25, 26, 27, 28, 29,
2114 ]
2115 .iter()
2116 .cloned()
2117 .map(ux::u7::new)
2118 .collect::<std::vec::Vec<u7>>()
2119 );
2120 }
2121
2122 #[test]
2123 fn move_payload_tail_ump_ten_places_back() {
2124 move_payload_tail_ten_places_back::<u32>();
2125 }
2126
2127 #[test]
2128 fn move_payload_tail_bytes_ten_places_back() {
2129 move_payload_tail_ten_places_back::<u8>();
2130 }
2131
2132 fn insert_rubbish_payload_front<U: crate::buffer::Unit>() {
2133 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2134 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2135 message.set_payload((0u8..30u8).map(u7::new));
2136 message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 0);
2137 assert_eq!(
2138 message.payload().collect::<std::vec::Vec<u7>>(),
2139 [
2140 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
2141 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
2142 44, 45, 46, 47, 48, 49, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2143 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
2144 ]
2145 .iter()
2146 .cloned()
2147 .map(ux::u7::new)
2148 .collect::<std::vec::Vec<u7>>()
2149 );
2150 }
2151
2152 #[test]
2153 fn insert_rubbish_payload_front_ump() {
2154 insert_rubbish_payload_front::<u32>();
2155 }
2156
2157 #[test]
2158 fn insert_rubbish_payload_front_bytes() {
2159 insert_rubbish_payload_front::<u8>();
2160 }
2161
2162 fn insert_rubbish_payload_back<U: crate::buffer::Unit>() {
2163 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2164 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2165 message.set_payload((0u8..30u8).map(u7::new));
2166 message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 30);
2167 assert_eq!(
2168 message.payload().collect::<std::vec::Vec<u7>>(),
2169 [
2170 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
2171 23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2172 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
2173 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
2174 ]
2175 .iter()
2176 .cloned()
2177 .map(ux::u7::new)
2178 .collect::<std::vec::Vec<u7>>()
2179 );
2180 }
2181
2182 #[test]
2183 fn insert_rubbish_payload_back_ump() {
2184 insert_rubbish_payload_back::<u32>();
2185 }
2186
2187 #[test]
2188 fn insert_rubbish_payload_back_bytes() {
2189 insert_rubbish_payload_back::<u8>();
2190 }
2191
2192 fn insert_rubbish_payload_middle<U: crate::buffer::Unit>() {
2193 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2194 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2195 message.set_payload((0u8..30u8).map(u7::new));
2196 message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 15);
2197 assert_eq!(
2198 message.payload().collect::<std::vec::Vec<u7>>(),
2199 [
2200 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2201 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2202 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 15, 16, 17,
2203 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
2204 ]
2205 .iter()
2206 .cloned()
2207 .map(ux::u7::new)
2208 .collect::<std::vec::Vec<u7>>()
2209 );
2210 }
2211
2212 #[test]
2213 fn insert_rubbish_payload_middle_ump() {
2214 insert_rubbish_payload_middle::<u32>();
2215 }
2216
2217 #[test]
2218 fn insert_rubbish_payload_middle_bytes() {
2219 insert_rubbish_payload_middle::<u8>();
2220 }
2221
2222 fn set_bytes<U: crate::buffer::Unit>() {
2223 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2224 message.set_payload((0u8..30u8).map(u7::new));
2225
2226 message.set_byte(ux::u7::new(0x7F), 4);
2227 message.set_byte(ux::u7::new(0x7E), 8);
2228 message.set_byte(ux::u7::new(0x7D), 12);
2229 message.set_byte(ux::u7::new(0x7C), 16);
2230 message.set_byte(ux::u7::new(0x7B), 17);
2231 message.set_byte(ux::u7::new(0x7A), 21);
2232 message.set_byte(ux::u7::new(0x79), 25);
2233 message.set_byte(ux::u7::new(0x78), 29);
2234
2235 let payload = message.payload().collect::<std::vec::Vec<u7>>();
2236
2237 assert_eq!(payload[4], ux::u7::new(0x7F));
2238 assert_eq!(payload[8], ux::u7::new(0x7E));
2239 assert_eq!(payload[12], ux::u7::new(0x7D));
2240 assert_eq!(payload[16], ux::u7::new(0x7C));
2241 assert_eq!(payload[17], ux::u7::new(0x7B));
2242 assert_eq!(payload[21], ux::u7::new(0x7A));
2243 assert_eq!(payload[25], ux::u7::new(0x79));
2244 assert_eq!(payload[29], ux::u7::new(0x78));
2245 }
2246
2247 #[test]
2248 fn set_bytes_ump() {
2249 set_bytes::<u32>();
2250 }
2251
2252 #[test]
2253 fn set_bytes_bytes() {
2254 set_bytes::<u8>();
2255 }
2256
2257 fn insert_payload_front_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
2258 let mut message = Sysex7::<[U; N]>::new();
2259 message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
2260 message
2261 .try_insert_payload((0..20u8).map(u7::new), 0)
2262 .unwrap();
2263 let payload = message.payload().collect::<std::vec::Vec<u7>>();
2264 assert_eq!(
2265 payload,
2266 [
2267 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
2268 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2269 26, 27, 28, 29
2270 ]
2271 .iter()
2272 .cloned()
2273 .map(ux::u7::new)
2274 .collect::<std::vec::Vec<u7>>()
2275 );
2276 }
2277
2278 #[test]
2279 fn insert_payload_front_fixed_size_buffer_ump() {
2280 insert_payload_front_fixed_size_buffer::<18, u32>();
2281 }
2282
2283 #[test]
2284 fn insert_payload_front_fixed_size_buffer_bytes() {
2285 insert_payload_front_fixed_size_buffer::<52, u8>();
2286 }
2287
2288 fn insert_payload_back_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
2289 let mut message = Sysex7::<[U; N]>::new();
2290 message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
2291 message
2292 .try_insert_payload((0..20u8).map(u7::new), 30)
2293 .unwrap();
2294 let payload = message.payload().collect::<std::vec::Vec<u7>>();
2295 assert_eq!(
2296 payload,
2297 [
2298 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
2299 23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2300 16, 17, 18, 19,
2301 ]
2302 .iter()
2303 .cloned()
2304 .map(ux::u7::new)
2305 .collect::<std::vec::Vec<u7>>()
2306 );
2307 }
2308
2309 #[test]
2310 fn insert_payload_back_fixed_size_buffer_ump() {
2311 insert_payload_back_fixed_size_buffer::<18, u32>();
2312 }
2313
2314 #[test]
2315 fn insert_payload_back_fixed_size_buffer_bytes() {
2316 insert_payload_back_fixed_size_buffer::<52, u8>();
2317 }
2318
2319 fn insert_payload_middle_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
2320 let mut message = Sysex7::<[U; N]>::new();
2321 message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
2322 message
2323 .try_insert_payload((0..20u8).map(u7::new), 15)
2324 .unwrap();
2325 let payload = message.payload().collect::<std::vec::Vec<u7>>();
2326 assert_eq!(
2327 payload,
2328 [
2329 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2330 11, 12, 13, 14, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
2331 27, 28, 29,
2332 ]
2333 .iter()
2334 .cloned()
2335 .map(ux::u7::new)
2336 .collect::<std::vec::Vec<u7>>()
2337 );
2338 }
2339
2340 #[test]
2341 fn insert_payload_middle_fixed_size_buffer_ump() {
2342 insert_payload_middle_fixed_size_buffer::<18, u32>();
2343 }
2344
2345 #[test]
2346 fn insert_payload_middle_fixed_size_buffer_bytes() {
2347 insert_payload_middle_fixed_size_buffer::<52, u8>();
2348 }
2349
2350 fn insert_payload_fixed_size_buffer_fail<const N: usize, U: crate::buffer::Unit>() {
2351 let mut message = Sysex7::<[U; N]>::new();
2352 message.try_set_payload((0u8..20).map(u7::new)).unwrap();
2353 assert_eq!(
2354 message.try_insert_payload((0u8..20).map(u7::new), 15),
2355 Err(crate::error::BufferOverflow),
2356 );
2357 }
2358
2359 #[test]
2360 fn insert_payload_fixed_size_buffer_fail_ump() {
2361 insert_payload_fixed_size_buffer_fail::<13, u32>();
2362 }
2363
2364 #[test]
2365 fn insert_payload_fixed_size_buffer_fail_bytes() {
2366 insert_payload_fixed_size_buffer_fail::<41, u8>();
2367 }
2368
2369 fn append_byte<U: crate::buffer::Unit>() {
2370 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2371 message.set_payload((0..20).map(u7::new));
2372 for i in 0u8..20 {
2373 message.append_byte(u7::new(i));
2374 }
2375 assert_eq!(
2376 message.payload().collect::<std::vec::Vec<u7>>(),
2377 [
2378 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
2379 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
2380 ]
2381 .iter()
2382 .cloned()
2383 .map(u7::new)
2384 .collect::<std::vec::Vec<u7>>(),
2385 );
2386 }
2387
2388 #[test]
2389 fn append_byte_ump() {
2390 append_byte::<u32>();
2391 }
2392
2393 #[test]
2394 fn append_byte_bytes() {
2395 append_byte::<u8>();
2396 }
2397
2398 fn append_payload<U: crate::buffer::Unit>() {
2399 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2400 message.set_payload((0..20).map(u7::new));
2401 message.append_payload((0..20).map(u7::new));
2402 assert_eq!(
2403 message.payload().collect::<std::vec::Vec<u7>>(),
2404 [
2405 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
2406 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
2407 ]
2408 .iter()
2409 .cloned()
2410 .map(u7::new)
2411 .collect::<std::vec::Vec<u7>>(),
2412 );
2413 }
2414
2415 #[test]
2416 fn append_payload_ump() {
2417 append_payload::<u32>();
2418 }
2419
2420 #[test]
2421 fn append_payload_bytes() {
2422 append_payload::<u8>();
2423 }
2424
2425 fn splice_payload<U: crate::buffer::Unit>() {
2426 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2427 message.set_payload((0..20).map(u7::new));
2428 message.splice_payload(core::iter::repeat_n(u7::new(0x7F), 30), 5..10);
2429 assert_eq!(
2430 message.payload().collect::<std::vec::Vec<u7>>(),
2431 [
2432 0, 1, 2, 3, 4, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
2433 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
2434 127, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
2435 ]
2436 .iter()
2437 .cloned()
2438 .map(u7::new)
2439 .collect::<std::vec::Vec<u7>>(),
2440 );
2441 }
2442
2443 #[test]
2444 fn splice_payload_ump() {
2445 splice_payload::<u32>();
2446 }
2447
2448 #[test]
2449 fn splice_payload_bytes() {
2450 splice_payload::<u8>();
2451 }
2452
2453 fn splice_rubbish_payload<U: crate::buffer::Unit>() {
2454 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2455 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2456 message.set_payload((0..20).map(u7::new));
2457 message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 7..16);
2458 assert_eq!(
2459 message.payload().collect::<std::vec::Vec<u7>>(),
2460 [
2461 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2462 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
2463 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 17, 18, 19,
2464 ]
2465 .iter()
2466 .cloned()
2467 .map(u7::new)
2468 .collect::<std::vec::Vec<u7>>(),
2469 );
2470 }
2471
2472 #[test]
2473 fn splice_rubbish_payload_ump() {
2474 splice_rubbish_payload::<u32>();
2475 }
2476
2477 #[test]
2478 fn splice_rubbish_payload_bytes() {
2479 splice_rubbish_payload::<u8>();
2480 }
2481
2482 fn splice_rubbish_payload_front<U: crate::buffer::Unit>() {
2483 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2484 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2485 message.set_payload((0..20).map(u7::new));
2486 message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 0..2);
2487 assert_eq!(
2488 message.payload().collect::<std::vec::Vec<u7>>(),
2489 [
2490 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
2491 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
2492 44, 45, 46, 47, 48, 49, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
2493 19,
2494 ]
2495 .iter()
2496 .cloned()
2497 .map(u7::new)
2498 .collect::<std::vec::Vec<u7>>(),
2499 );
2500 }
2501
2502 #[test]
2503 fn splice_rubbish_payload_front_ump() {
2504 splice_rubbish_payload_front::<u32>();
2505 }
2506
2507 #[test]
2508 fn splice_rubbish_payload_front_bytes() {
2509 splice_rubbish_payload_front::<u8>();
2510 }
2511
2512 fn splice_rubbish_payload_end<U: crate::buffer::Unit>() {
2513 use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
2514 let mut message = Sysex7::<std::vec::Vec<U>>::new();
2515 message.set_payload((0..20).map(u7::new));
2516 message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 19..20);
2517 assert_eq!(
2518 message.payload().collect::<std::vec::Vec<u7>>(),
2519 [
2520 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 1, 2, 3, 4, 5,
2521 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
2522 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
2523 49,
2524 ]
2525 .iter()
2526 .cloned()
2527 .map(u7::new)
2528 .collect::<std::vec::Vec<u7>>(),
2529 );
2530 }
2531
2532 #[test]
2533 fn splice_rubbish_payload_end_ump() {
2534 splice_rubbish_payload_end::<u32>();
2535 }
2536
2537 #[test]
2538 fn splice_rubbish_payload_end_bytes() {
2539 splice_rubbish_payload_end::<u8>();
2540 }
2541}