midi2/
sysex7.rs

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))]
16/// A semantic wrapper type around MIDI System Exclusive 7bit data.
17/// See the [module docs](crate::sysex7) for more detailed info
18struct 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
44// ***********************************************************************
45// properties
46
47struct 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            // only called at initialization time.
116            // the payload will be empty
117            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
255// ***********************************************************************
256// trait impls
257
258impl<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    // convert payload
387    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                // can't assume a compact payload here:
481                // linear complexity
482                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                    // erase old end bit
538                    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                    // erase old end bit
568                    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                // data is written into the buffer contiguously
590                // meaning only the last packet may have a size < 6
591                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}
687//
688// move the payload bytes in-place so that they maximally fill the
689// underlying buffer
690fn 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    // copy the data in place
704    loop {
705        // loop through the packets
706
707        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            // loop through the payload within the current packet
717            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    // reset the statuses of the packets
735    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    // first packet
770    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            // start packet
775            first_packet[0].set_nibble(2, STATUS_START);
776            first_packet[0].set_nibble(3, u4::new(6));
777        } else {
778            // complete packet
779            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            // middle packet
789            chunk[0].set_nibble(2, STATUS_CONTINUE);
790            chunk[0].set_nibble(3, u4::new(6));
791        } else {
792            // last packet
793            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                    // zero off the end of the packet
801                    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// ***********************************************************************
825// payload iterator
826
827/// An iterator over the payload bytes of a [Sysex7] message.
828///
829/// # When U = [u8]
830///
831/// Payload bytes are contiguous in the message buffer.
832///
833/// Custom implementation of
834/// [nth](PayloadIterator::nth)
835/// has complexity O(1).
836///
837/// # When U = [u32]
838///
839/// Payload bytes are distributed non-contiguously across the message packets.
840///
841/// For this reason the custom implementation of
842/// [nth](PayloadIterator::nth)
843/// has complexity O(n), where n is the size of the message buffer.
844#[derive(Debug, Clone)]
845pub struct PayloadIterator<'a, U: crate::buffer::Unit> {
846    data: &'a [U],
847    payload_index: usize,
848    // unused in bytes mode
849    packet_index: usize,
850    // unused in bytes mode
851    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    /// # Complexity
886    ///
887    /// O(1) when U: [crate::buffer::Bytes].
888    ///
889    /// O(n) when U: [crate::buffer::Ump], where n is the size of the buffer.
890    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                        // first we check to see whether the requested byte lies
904                        // within the first packet where we are potentially already offset
905                        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                    // we then cycle through all the packets until we travelled as far as the
917                    // requested location
918                    loop {
919                        let (packet_index, packet) = packets.next()?;
920                        let size = Self::packet_size(packet);
921                        if n < size {
922                            // we found the requested packet
923                            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                    // if we failed it means we ran out of data
938                    // so we set the iterator into finished state
939                    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            // end of packet
990            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}