#![doc = include_str!("sysex7/README.md")]
use crate::{
detail::{common_properties, helpers as message_helpers, BitOps},
traits::{Sysex, SysexInternal},
ux::{self, u7},
};
mod packet;
pub use packet::Packet;
pub(crate) const UMP_MESSAGE_TYPE: u8 = 0x3;
#[midi2_proc::generate_message(MinSizeUmp(2), MinSizeBytes(2))]
struct Sysex7 {
#[property(common_properties::UmpMessageTypeProperty<UMP_MESSAGE_TYPE>)]
ump_type: (),
#[property(Sysex7BytesBeginByte)]
bytes_begin_byte: (),
#[property(Sysex7BytesEndByte)]
bytes_end_byte: (),
#[property(ConsistentStatuses)]
consistent_statuses: (),
#[property(ValidPacketSizes)]
valid_packet_sizes: (),
#[property(GroupProperty)]
group: crate::ux::u4,
#[property(SysexPayloadPlaceholder)]
#[readonly]
#[writeonly]
sysex_payload: (),
}
const ERR_NO_BEGIN_BYTE: &str = "Sysex messages should begin 0xF0";
const ERR_NO_END_BYTE: &str = "Sysex messages should end 0xF7";
const ERR_INVALID_PACKET_SIZE: &str = "Size field can not exceed 6";
const START_BYTE: u8 = 0xF0;
const END_BYTE: u8 = 0xF7;
struct Sysex7BytesBeginByte;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for Sysex7BytesBeginByte {
type Type = ();
}
impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
for Sysex7BytesBeginByte
{
fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
if buffer.specialise_u8()[0] != START_BYTE {
Err(crate::error::InvalidData(ERR_NO_BEGIN_BYTE))
} else {
Ok(())
}
}
crate::buffer::UNIT_ID_U32 => Ok(()),
_ => unreachable!(),
}
}
fn read(_buffer: &'a B) -> Self::Type {}
}
impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
for Sysex7BytesBeginByte
{
fn write(buffer: &mut B, _: Self::Type) {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
buffer.specialise_u8_mut()[0] = START_BYTE;
}
}
fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
Ok(())
}
fn default() -> Self::Type {}
}
struct Sysex7BytesEndByte;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for Sysex7BytesEndByte {
type Type = ();
}
impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
for Sysex7BytesEndByte
{
fn read(_buffer: &'a B) -> Self::Type {}
fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => buffer
.specialise_u8()
.iter()
.position(|b| *b == 0xF7)
.map(|_| ())
.ok_or(crate::error::InvalidData(ERR_NO_END_BYTE)),
crate::buffer::UNIT_ID_U32 => Ok(()),
_ => unreachable!(),
}
}
}
impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
for Sysex7BytesEndByte
{
fn write(buffer: &mut B, _: Self::Type) {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
buffer.specialise_u8_mut()[1] = END_BYTE;
}
}
fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
Ok(())
}
fn default() -> Self::Type {}
}
struct ConsistentStatuses;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for ConsistentStatuses {
type Type = ();
}
impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
for ConsistentStatuses
{
fn read(_buffer: &'a B) -> Self::Type {}
fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
message_helpers::validate_sysex_group_statuses(
buffer.specialise_u32(),
|p| u8::from(p[0].nibble(2)) == 0x0,
|p| u8::from(p[0].nibble(2)) == 0x1,
|p| u8::from(p[0].nibble(2)) == 0x2,
|p| u8::from(p[0].nibble(2)) == 0x3,
2,
crate::ux::u4::new(UMP_MESSAGE_TYPE),
)?;
}
Ok(())
}
}
impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
for ConsistentStatuses
{
fn write(_: &mut B, _: Self::Type) {}
fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
Ok(())
}
fn default() -> Self::Type {}
}
struct ValidPacketSizes;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for ValidPacketSizes {
type Type = ();
}
impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B>
for ValidPacketSizes
{
fn read(_buffer: &'a B) -> Self::Type {}
fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
if buffer
.specialise_u32()
.chunks_exact(2)
.any(|p| u8::from(p[0].nibble(3)) > 6)
{
Err(crate::error::InvalidData(ERR_INVALID_PACKET_SIZE))
} else {
Ok(())
}
} else {
Ok(())
}
}
}
impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
for ValidPacketSizes
{
fn write(_buffer: &mut B, _v: Self::Type) {}
fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
Ok(())
}
fn default() -> Self::Type {}
}
struct GroupProperty;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for GroupProperty {
type Type = ux::u4;
}
impl<'a, B: crate::buffer::Buffer> crate::detail::property::ReadProperty<'a, B> for GroupProperty {
fn read(buffer: &'a B) -> Self::Type {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
buffer.specialise_u32()[0].nibble(1)
} else {
Default::default()
}
}
fn validate(buffer: &B) -> Result<(), crate::error::InvalidData> {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
message_helpers::sysex_group_consistent_groups(
buffer.specialise_u32(),
2,
crate::ux::u4::new(UMP_MESSAGE_TYPE),
)
} else {
Ok(())
}
}
}
impl<B: crate::buffer::Buffer + crate::buffer::BufferMut> crate::detail::property::WriteProperty<B>
for GroupProperty
{
fn write(buffer: &mut B, group: Self::Type) {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U32 {
const TYPE: ux::u4 = ux::u4::new(UMP_MESSAGE_TYPE);
for packet in buffer
.specialise_u32_mut()
.chunks_exact_mut(2)
.take_while(|packet| packet[0].nibble(0) == TYPE)
{
packet[0].set_nibble(1, group);
}
}
}
fn validate(_v: &Self::Type) -> Result<(), crate::error::InvalidData> {
Ok(())
}
fn default() -> Self::Type {
Default::default()
}
}
#[allow(dead_code)]
struct SysexPayloadPlaceholder;
impl<B: crate::buffer::Buffer> crate::detail::property::Property<B> for SysexPayloadPlaceholder {
type Type = ();
}
impl<B: crate::buffer::Buffer> crate::traits::Size<B> for Sysex7<B> {
fn size(&self) -> usize {
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
self.0
.specialise_u8()
.iter()
.position(|b| *b == 0xF7)
.expect("Message is in an invalid state. No end byte.")
+ 1
}
crate::buffer::UNIT_ID_U32 => {
self.0
.specialise_u32()
.chunks_exact(2)
.position(|p| {
let status: u8 = p[0].nibble(2).into();
status == 0x0 || status == 0x3
})
.expect("Message is in an invalid state. Couldn't find end packet.")
* 2
+ 2
}
_ => unreachable!(),
}
}
}
impl<
A: crate::buffer::Bytes,
B: crate::buffer::Ump
+ crate::buffer::BufferMut
+ crate::buffer::BufferDefault
+ crate::buffer::BufferResize,
> crate::traits::FromBytes<Sysex7<A>> for Sysex7<B>
{
fn from_bytes(other: Sysex7<A>) -> Self {
try_from_other(
&other,
|s: &mut B, sz| {
s.resize(sz);
Ok(())
},
|s, p| {
s.set_payload(p);
Ok(())
},
)
.unwrap()
}
}
impl<
A: crate::buffer::Ump,
B: crate::buffer::Bytes
+ crate::buffer::BufferMut
+ crate::buffer::BufferDefault
+ crate::buffer::BufferResize,
> crate::traits::FromUmp<Sysex7<A>> for Sysex7<B>
{
fn from_ump(other: Sysex7<A>) -> Self {
try_from_other(
&other,
|s: &mut B, sz| {
s.resize(sz);
Ok(())
},
|s, p| {
s.set_payload(p);
Ok(())
},
)
.unwrap()
}
}
impl<
A: crate::buffer::Bytes,
B: crate::buffer::Ump
+ crate::buffer::BufferMut
+ crate::buffer::BufferDefault
+ crate::buffer::BufferTryResize,
> crate::traits::TryFromBytes<Sysex7<A>> for Sysex7<B>
{
fn try_from_bytes(other: Sysex7<A>) -> Result<Self, crate::error::BufferOverflow> {
try_from_other(
&other,
|s: &mut B, sz| s.try_resize(sz),
|s, p| s.try_set_payload(p),
)
}
}
impl<
A: crate::buffer::Ump,
B: crate::buffer::Bytes
+ crate::buffer::BufferMut
+ crate::buffer::BufferDefault
+ crate::buffer::BufferTryResize,
> crate::traits::TryFromUmp<Sysex7<A>> for Sysex7<B>
{
fn try_from_ump(other: Sysex7<A>) -> Result<Self, crate::error::BufferOverflow> {
try_from_other(
&other,
|s: &mut B, sz| s.try_resize(sz),
|s, p| s.try_set_payload(p),
)
}
}
fn try_from_other<
A: crate::buffer::Buffer,
B: crate::buffer::Buffer + crate::buffer::BufferMut + crate::buffer::BufferDefault,
R: Fn(&mut B, usize) -> Result<(), crate::error::BufferOverflow>,
S: Fn(&mut Sysex7<B>, PayloadIterator<A::Unit>) -> Result<(), crate::error::BufferOverflow>,
>(
other: &Sysex7<A>,
try_resize: R,
try_set_payload: S,
) -> Result<Sysex7<B>, crate::error::BufferOverflow> {
let mut buffer = <B as crate::buffer::BufferDefault>::default();
try_resize(
&mut buffer,
<Sysex7<B> as crate::traits::MinSize<B>>::MIN_SIZE,
)?;
convert_generated_properties(&other.0, &mut buffer);
let mut ret = Sysex7::<B>(buffer);
try_set_payload(&mut ret, other.payload())?;
Ok(ret)
}
fn convert_generated_properties<
A: crate::buffer::Buffer,
B: crate::buffer::Buffer + crate::buffer::BufferMut,
>(
buffer_a: &A,
buffer_b: &mut B,
) {
type MessageType = common_properties::UmpMessageTypeProperty<UMP_MESSAGE_TYPE>;
<MessageType as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
<Sysex7BytesBeginByte as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
<Sysex7BytesEndByte as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
<ConsistentStatuses as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
<ValidPacketSizes as crate::detail::property::WriteProperty<B>>::write(buffer_b, ());
<GroupProperty as crate::detail::property::WriteProperty<B>>::write(
buffer_b,
<GroupProperty as crate::detail::property::ReadProperty<A>>::read(buffer_a),
);
}
impl<B: crate::buffer::Buffer> Sysex<B> for Sysex7<B> {
type Byte = ux::u7;
type PayloadIterator<'a>
= PayloadIterator<'a, B::Unit>
where
B::Unit: 'a,
Self: 'a;
fn payload<'a>(&'a self) -> Self::PayloadIterator<'a>
where
B::Unit: 'a,
{
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => PayloadIterator {
data: &self.0.buffer()[1..self.data().len() - 1],
payload_index: 0,
packet_index: 0,
size_cache: 0,
},
crate::buffer::UNIT_ID_U32 => {
let size_cache = self
.data()
.specialise_u32()
.chunks_exact(2)
.map(PayloadIterator::<B::Unit>::packet_size)
.sum::<usize>();
PayloadIterator {
data: self.0.buffer(),
payload_index: 0,
packet_index: 0,
size_cache,
}
}
_ => unreachable!(),
}
}
fn set_payload<D>(&mut self, data: D)
where
D: core::iter::Iterator<Item = Self::Byte>,
B: crate::buffer::BufferMut + crate::buffer::BufferResize,
{
<Self as SysexInternal<B>>::resize(self, 0);
self.insert_payload(data, 0);
}
fn try_set_payload<D>(
&mut self,
data: D,
) -> core::result::Result<(), crate::error::BufferOverflow>
where
D: core::iter::Iterator<Item = Self::Byte>,
B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
{
<Self as SysexInternal<B>>::try_resize(self, 0)?;
self.try_insert_payload(data, 0)
}
fn set_byte(&mut self, byte: ux::u7, mut index: usize)
where
B: crate::buffer::BufferMut,
{
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
let buffer = self.buffer_access_mut().specialise_u8_mut();
buffer[index + 1].set_septet(0, byte);
}
crate::buffer::UNIT_ID_U32 => {
let buffer = self.buffer_access_mut().specialise_u32_mut();
let mut packet_index = 0;
loop {
let sz = (u8::from(buffer[packet_index * 2].nibble(3))) as usize;
if index < sz {
buffer[packet_index * 2 + (index + 2) / 4]
.set_septet((index + 2) % 4, byte);
break;
}
index -= sz;
packet_index += 1;
}
}
_ => unreachable!(),
}
}
fn splice_payload<D, R>(&mut self, data: D, range: R)
where
D: core::iter::Iterator<Item = Self::Byte>,
B: crate::buffer::BufferMut + crate::buffer::BufferResize,
R: core::ops::RangeBounds<usize>,
{
message_helpers::splice_sysex_data(self, data, range)
}
fn try_splice_payload<D, R>(
&mut self,
data: D,
range: R,
) -> core::result::Result<(), crate::error::BufferOverflow>
where
D: core::iter::Iterator<Item = Self::Byte>,
B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
R: core::ops::RangeBounds<usize>,
{
message_helpers::try_splice_sysex_data(self, data, range)
}
fn payload_size(&self) -> usize {
self.payload().len()
}
}
impl<B: crate::buffer::Buffer> SysexInternal<B> for Sysex7<B> {
fn resize(&mut self, payload_size: usize)
where
B: crate::buffer::BufferMut + crate::buffer::BufferResize,
{
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
let buffer_sz = payload_size + 2;
let old_payload_size = self.payload_size();
self.0.resize(buffer_sz);
if payload_size > old_payload_size {
self.0.specialise_u8_mut()[old_payload_size + 1] = 0;
}
self.0.specialise_u8_mut()[buffer_sz - 1] = END_BYTE;
}
crate::buffer::UNIT_ID_U32 => try_resize_ump(self, payload_size, |s, sz| {
s.0.resize(sz);
Ok(())
})
.unwrap(),
_ => unreachable!(),
}
}
fn try_resize(
&mut self,
payload_size: usize,
) -> core::result::Result<(), crate::traits::SysexTryResizeError>
where
B: crate::buffer::BufferMut + crate::buffer::BufferTryResize,
{
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
let old_payload_size = self.payload_size();
let mut buffer_sz = payload_size + 2;
let result = self.0.try_resize(buffer_sz).map_err(|_| {
buffer_sz = self.0.buffer().len();
crate::traits::SysexTryResizeError(buffer_sz.saturating_sub(2))
});
if buffer_sz > old_payload_size {
self.0.specialise_u8_mut()[old_payload_size + 1] = 0;
}
self.0.specialise_u8_mut()[buffer_sz - 1] = END_BYTE;
result
}
crate::buffer::UNIT_ID_U32 => {
try_resize_ump(self, payload_size, |s, sz| s.0.try_resize(sz))
}
_ => unreachable!(),
}
}
fn write_datum(&mut self, datum: Self::Byte, payload_index: usize)
where
B: crate::buffer::BufferMut,
{
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
self.0.specialise_u8_mut()[payload_index + 1] = datum.into();
}
crate::buffer::UNIT_ID_U32 => {
let buffer_index = 2 * (payload_index / 6);
let byte_index = payload_index % 6;
self.0.specialise_u32_mut()[buffer_index + (byte_index + 2) / 4]
.set_septet((byte_index + 2) % 4, datum);
}
_ => unreachable!(),
}
}
fn move_payload_tail(&mut self, tail: usize, to: usize)
where
B: crate::buffer::BufferMut,
{
debug_assert!(is_compact(self));
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
let payload_size = self.payload_size();
let buffer = self.buffer_access_mut().specialise_u8_mut();
match to.cmp(&tail) {
core::cmp::Ordering::Greater => {
let d = payload_size.saturating_sub(to);
buffer.copy_within(1 + tail..1 + tail + d, to + 1);
}
core::cmp::Ordering::Less => {
buffer.copy_within(1 + tail..1 + payload_size, to + 1);
}
_ => {}
}
}
crate::buffer::UNIT_ID_U32 => {
let payload_size = self.payload_size();
let buffer = self.buffer_access_mut().specialise_u32_mut();
let index = |payload_index| {
let byte_index = payload_index + 2 * (1 + payload_index / 6);
(byte_index / 4, byte_index % 4)
};
match to.cmp(&tail) {
core::cmp::Ordering::Greater => {
let d = to - tail;
for (src, dst) in (tail..(payload_size - d))
.rev()
.map(|i| (index(i), index(i + d)))
{
let v = buffer[src.0].octet(src.1);
buffer[dst.0].set_octet(dst.1, v);
}
}
core::cmp::Ordering::Less => {
let d = tail - to;
for (src, dst) in (tail..payload_size).map(|i| (index(i), index(i - d))) {
let v = buffer[src.0].octet(src.1);
buffer[dst.0].set_octet(dst.1, v);
}
}
_ => {}
}
}
_ => unreachable!(),
}
}
fn compact(&mut self)
where
B: crate::buffer::BufferMut,
{
if !is_compact(self) {
compact(self);
}
}
}
fn is_compact<B: crate::buffer::Buffer>(sysex: &Sysex7<B>) -> bool {
match <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
crate::buffer::UNIT_ID_U8 => true,
crate::buffer::UNIT_ID_U32 => {
use crate::detail::BitOps;
for chunk in sysex
.0
.buffer()
.specialise_u32()
.chunks_exact(4)
.take_while(|packet| u8::from(packet[0].nibble(0)) == UMP_MESSAGE_TYPE)
{
let status: u8 = chunk[0].nibble(2).into();
let is_begin = status == 0x1;
let is_continue = status == 0x2;
let payload_size_in_packet: u8 = chunk[0].nibble(3).into();
if (is_begin || is_continue) && payload_size_in_packet != 6 {
return false;
}
}
true
}
_ => unreachable!(),
}
}
fn compact<B: crate::buffer::Buffer + crate::buffer::BufferMut>(sysex: &mut Sysex7<B>) {
if <B::Unit as crate::buffer::UnitPrivate>::UNIT_ID == crate::buffer::UNIT_ID_U8 {
return;
}
use crate::{detail::BitOps, BufferAccess};
let payload_size = sysex.payload_size();
let buffer = sysex.buffer_access_mut().specialise_u32_mut();
let mut src_packet_index: usize = 0;
let mut dst_packet_index = 0;
let mut dst_payload_index = 0;
loop {
let status: u8 = buffer[src_packet_index * 2].nibble(2).into();
if status == 0x0 {
break;
}
let size: u8 = buffer[src_packet_index * 2].nibble(3).into();
for i in 0..size as usize {
let v = buffer[src_packet_index * 2 + (i + 2) / 4].octet((i + 2) % 4);
buffer[dst_packet_index * 2 + (dst_payload_index + 2) / 4]
.set_octet((dst_payload_index + 2) % 4, v);
dst_payload_index += 1;
if dst_payload_index == 6 {
dst_packet_index += 1;
dst_payload_index = 0;
}
}
src_packet_index += 1;
if status == 0x3 {
break;
}
}
try_resize_ump(sysex, payload_size, |_, _| Ok(())).expect("Resizing down should never fail");
}
fn try_resize_ump<
B: crate::buffer::Buffer + crate::buffer::BufferMut,
ResizeBuffer: Fn(&mut Sysex7<B>, usize) -> Result<(), crate::error::BufferOverflow>,
>(
sysex: &mut Sysex7<B>,
mut payload_size: usize,
try_resize_buffer: ResizeBuffer,
) -> Result<(), crate::traits::SysexTryResizeError> {
use ux::u4;
let mut buffer_size = buffer_size_from_payload_size_ump(payload_size);
let resize_result = try_resize_buffer(sysex, buffer_size);
if resize_result.is_err() {
buffer_size = sysex.0.buffer().len();
payload_size = (buffer_size / 2) * 6;
}
let mut iter = sysex
.0
.specialise_u32_mut()
.chunks_exact_mut(2)
.take(buffer_size / 2)
.peekable();
let mut group = None;
const MESSAGE_TYPE: u4 = u4::new(UMP_MESSAGE_TYPE);
const STATUS_COMPLETE: u4 = u4::new(0x0);
const STATUS_START: u4 = u4::new(0x1);
const STATUS_CONTINUE: u4 = u4::new(0x2);
const STATUS_END: u4 = u4::new(0x3);
if let Some(first_packet) = iter.next() {
first_packet[0].set_nibble(0, MESSAGE_TYPE);
group = Some(first_packet[0].nibble(1));
if iter.peek().is_some() {
first_packet[0].set_nibble(2, STATUS_START);
first_packet[0].set_nibble(3, u4::new(6));
} else {
first_packet[0].set_nibble(2, STATUS_COMPLETE);
first_packet[0].set_nibble(3, u4::new(payload_size as u8));
}
}
while let Some(chunk) = iter.next() {
chunk[0].set_nibble(0, MESSAGE_TYPE);
chunk[0].set_nibble(1, group.unwrap());
if iter.peek().is_some() {
chunk[0].set_nibble(2, STATUS_CONTINUE);
chunk[0].set_nibble(3, u4::new(6));
} else {
chunk[0].set_nibble(2, STATUS_END);
match payload_size % 6 {
0 => {
chunk[0].set_nibble(3, u4::new(6));
}
r => {
chunk[0].set_nibble(3, u4::new(r as u8));
for i in r..6 {
chunk[(i + 2) / 4].set_octet((i + 2) % 4, 0x0);
}
}
};
}
}
resize_result.map_err(|_| crate::traits::SysexTryResizeError(payload_size))
}
fn buffer_size_from_payload_size_ump(payload_size: usize) -> usize {
if payload_size.is_multiple_of(6) {
if payload_size == 0 {
2
} else {
payload_size / 3
}
} else {
2 * (payload_size / 6 + 1)
}
}
#[derive(Debug, Clone)]
pub struct PayloadIterator<'a, U: crate::buffer::Unit> {
data: &'a [U],
payload_index: usize,
packet_index: usize,
size_cache: usize,
}
impl<U: crate::buffer::Unit> core::iter::Iterator for PayloadIterator<'_, U> {
type Item = ux::u7;
fn next(&mut self) -> Option<Self::Item> {
match U::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
let data = <U as crate::buffer::UnitPrivate>::specialise_buffer_u8(self.data);
if self.payload_index >= data.len() {
None
} else {
let ret = Some(u7::new(data[self.payload_index]));
self.payload_index += 1;
ret
}
}
crate::buffer::UNIT_ID_U32 => {
if self.finished_ump() {
return None;
}
self.skip_empty_packets_ump();
let ret = Some(self.value_ump());
self.advance_ump();
ret
}
_ => unreachable!(),
}
}
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
match U::UNIT_ID {
crate::buffer::UNIT_ID_U8 => {
self.payload_index += n;
self.next()
}
crate::buffer::UNIT_ID_U32 => {
let mut do_nth = || {
let mut packets = self.data_ump()[self.packet_index * 2..]
.chunks_exact(2)
.enumerate();
{
let remaining = Self::packet_size(packets.next()?.1) - self.payload_index;
if n < remaining {
self.payload_index += n;
self.size_cache -= n;
return self.next();
} else {
n -= remaining;
self.size_cache -= remaining;
}
}
loop {
let (packet_index, packet) = packets.next()?;
let size = Self::packet_size(packet);
if n < size {
self.packet_index += packet_index;
self.payload_index = n;
self.size_cache -= n;
break;
}
n -= size;
self.size_cache -= size;
}
self.next()
};
let ret = do_nth();
if ret.is_none() {
self.packet_index = self.data.len() / 2;
self.size_cache = 0;
}
ret
}
_ => unreachable!(),
}
}
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.size_cache, Some(self.size_cache))
}
}
impl<'a, U: crate::buffer::Unit> PayloadIterator<'a, U> {
fn data_ump(&self) -> &'a [u32] {
<U as crate::buffer::UnitPrivate>::specialise_buffer_u32(self.data)
}
fn value_ump(&self) -> ux::u7 {
let buffer_index = self.packet_index * 2 + (self.payload_index + 2) / 4;
let octet_index = (self.payload_index + 2) % 4;
self.data_ump()[buffer_index].septet(octet_index)
}
fn finished_ump(&self) -> bool {
self.size_cache == 0
}
fn skip_empty_packets_ump(&mut self) {
while !self.finished_ump() && self.current_packet_size_ump() == 0 {
self.payload_index = 0;
self.packet_index += 1;
}
}
fn advance_ump(&mut self) {
self.payload_index += 1;
if !self.finished_ump() {
self.size_cache -= 1;
}
if self.payload_index == self.current_packet_size_ump() {
self.packet_index += 1;
self.payload_index = 0;
}
self.skip_empty_packets_ump();
}
fn current_packet_size_ump(&self) -> usize {
Self::packet_size(&self.data_ump()[self.packet_index * 2..self.packet_index * 2 + 2])
}
fn packet_size(packet: &[u32]) -> usize {
u8::from(packet[0].nibble(3)) as usize
}
}
impl<U: crate::buffer::Unit> core::iter::FusedIterator for PayloadIterator<'_, U> {}
impl<U: crate::buffer::Unit> core::iter::ExactSizeIterator for PayloadIterator<'_, U> {
fn len(&self) -> usize {
match U::UNIT_ID {
crate::buffer::UNIT_ID_U8 => self.data[self.payload_index..].len(),
crate::buffer::UNIT_ID_U32 => self.size_cache,
_ => unreachable!(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
traits::{FromBytes, FromUmp, Grouped, RebufferInto, Sysex},
ux::*,
};
use pretty_assertions::assert_eq;
#[test]
fn new_bytes() {
let message = Sysex7::<std::vec::Vec<u8>>::new();
assert_eq!(message, Sysex7(std::vec![0xF0, 0xF7]));
}
#[test]
fn bytes_try_new_with_buffer() {
let mut buffer = [0x0_u8; 50];
let message = Sysex7::try_new_with_buffer(&mut buffer[..]);
assert_eq!(message.unwrap().data(), &[0xF0, 0xF7][..]);
}
#[test]
fn bytes_try_new_with_buffer_write_payload_data() {
let mut buffer = [0x0_u8; 50];
let mut message = Sysex7::try_new_with_buffer(&mut buffer[..]).unwrap();
message.try_set_payload((0..10).map(u7::new)).unwrap();
assert_eq!(
message.data(),
&[0xF0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xF7][..]
);
}
#[test]
fn try_new_bytes() {
let message = Sysex7::<[u8; 2]>::try_new().expect("Buffer is large enough");
assert_eq!(message, Sysex7([0xF0, 0xF7]));
}
#[test]
fn data_bytes() {
let message = Sysex7::<std::vec::Vec<u8>>::new();
assert_eq!(message.data(), &[0xF0, 0xF7]);
}
#[test]
fn try_from_bytes() {
assert_eq!(
Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7_u8][..]),
Ok(Sysex7(&[0xF0, 0x0, 0x1, 0x2, 0xF7][..])),
)
}
#[test]
fn try_from_oversized_bytes() {
assert_eq!(
Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7, 0x0][..]),
Ok(Sysex7(&[0xF0, 0x0, 0x1, 0x2, 0xF7, 0x0][..])),
)
}
#[test]
fn data_oversized_bytes() {
assert_eq!(
Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8, 0xF7, 0x0][..])
.unwrap()
.data(),
&[0xF0, 0x0, 0x1, 0x2, 0xF7],
);
}
#[test]
fn try_from_bytes_with_no_end_byte() {
assert_eq!(
Sysex7::try_from(&[0xF0_u8, 0x0_u8, 0x1_u8, 0x2_u8][..]),
Err(crate::error::InvalidData(ERR_NO_END_BYTE))
)
}
#[test]
fn try_from_bytes_with_no_begin_byte() {
assert_eq!(
Sysex7::try_from(&[0x0_u8, 0x1_u8, 0x2_u8, 0xF7_u8][..]),
Err(crate::error::InvalidData(ERR_NO_BEGIN_BYTE))
)
}
#[test]
fn new_ump() {
let message = Sysex7::<std::vec::Vec<u32>>::new();
assert_eq!(message, Sysex7(std::vec![0x3000_0000, 0x0000_0000,]));
}
#[test]
fn data_ump() {
let message = Sysex7::<std::vec::Vec<u32>>::new();
assert_eq!(message.data(), &[0x3000_0000, 0x0000_0000,]);
}
#[test]
fn try_from_ump() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Ok(Sysex7(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
))
);
}
#[test]
fn set_group_ump() {
let mut message: Sysex7<std::vec::Vec<u32>> = Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..],
)
.unwrap()
.rebuffer_into();
message.set_group(u4::new(0x5));
assert_eq!(
message,
Sysex7(std::vec![
0x3516_0001_u32,
0x0203_0405_u32,
0x3526_0607_u32,
0x0809_0A0B_u32,
0x3533_0C0D_u32,
0x0E00_0000_u32,
])
);
}
#[test]
fn try_from_oversized_ump() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
0x0000_0000_u32,
0x0000_0000_u32,
][..]
),
Ok(Sysex7(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
0x0000_0000_u32,
0x0000_0000_u32,
][..]
))
);
}
#[test]
fn data_oversized_ump() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
0x0000_0000_u32,
0x0000_0000_u32,
][..]
)
.unwrap()
.data(),
&[
0x3416_0001,
0x0203_0405,
0x3426_0607,
0x0809_0A0B,
0x3433_0C0D,
0x0E00_0000,
],
);
}
#[test]
fn data_odd_sized_buffer_ump() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
0x0000_0000_u32,
][..]
)
.unwrap()
.data(),
&[
0x3416_0001,
0x0203_0405,
0x3426_0607,
0x0809_0A0B,
0x3433_0C0D,
0x0E00_0000,
],
);
}
#[test]
fn try_from_ump_inconsistent_groups() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3326_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Err(crate::error::InvalidData(
message_helpers::ERR_INCONSISTENT_GROUPS
)),
);
}
#[test]
fn try_from_ump_incorrect_end_status() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3403_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Err(crate::error::InvalidData(
message_helpers::ERR_SYSEX_EXPECTED_END
)),
);
}
#[test]
fn try_from_ump_incorrect_complete_status() {
assert_eq!(
Sysex7::try_from(&[0x3416_0001_u32, 0x0203_0405_u32,][..]),
Err(crate::error::InvalidData(
message_helpers::ERR_SYSEX_EXPECTED_COMPLETE
)),
);
}
#[test]
fn try_from_ump_incorrect_begin_status() {
assert_eq!(
Sysex7::try_from(
&[
0x3406_0001_u32,
0x0203_0405_u32,
0x3426_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Err(crate::error::InvalidData(
message_helpers::ERR_SYSEX_EXPECTED_BEGIN
)),
);
}
#[test]
fn try_from_ump_incorrect_continue_status() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3456_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Err(crate::error::InvalidData(
message_helpers::ERR_SYSEX_EXPECTED_CONTINUE
)),
);
}
#[test]
fn try_from_ump_invalid_packet_sizes() {
assert_eq!(
Sysex7::try_from(
&[
0x3416_0001_u32,
0x0203_0405_u32,
0x3427_0607_u32,
0x0809_0A0B_u32,
0x3433_0C0D_u32,
0x0E00_0000_u32,
][..]
),
Err(crate::error::InvalidData(ERR_INVALID_PACKET_SIZE)),
);
}
#[test]
fn set_payload_bytes() {
let mut message = Sysex7::<std::vec::Vec<u8>>::new();
message.set_payload((0u8..20u8).map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xF7,
])
);
}
#[test]
fn try_set_payload_bytes() {
let mut message = Sysex7::<[u8; 22]>::new();
message.try_set_payload((0u8..20u8).map(u7::new)).unwrap();
assert_eq!(
message,
Sysex7([
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xF7,
])
);
}
#[test]
fn try_set_payload_bytes_fail() {
let mut message = Sysex7::<[u8; 22]>::new();
assert_eq!(
message.try_set_payload((0u8..30u8).map(u7::new)),
Err(crate::error::BufferOverflow),
);
}
#[test]
fn set_payload_ump() {
let mut message = Sysex7::<std::vec::Vec<u32>>::new();
message.set_payload((0u8..30u8).map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0x3016_0001,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
])
);
}
#[test]
fn set_rubbish_payload_ump() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<u32>>::new();
message.set_payload(RubbishPayloadIterator::new().map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0x3016_0001,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3026_1819,
0x1A1B_1C1D,
0x3026_1E1F,
0x2021_2223,
0x3026_2425,
0x2627_2829,
0x3026_2A2B,
0x2C2D_2E2F,
0x3032_3031,
0x0000_0000,
])
);
}
#[test]
fn try_set_rubbish_payload_to_fixed_size_buffer_ump() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<[u32; 18]>::new();
message
.try_set_payload(RubbishPayloadIterator::new().map(u7::new))
.expect("Shouldn't fail");
assert_eq!(
message,
Sysex7([
0x3016_0001,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3026_1819,
0x1A1B_1C1D,
0x3026_1E1F,
0x2021_2223,
0x3026_2425,
0x2627_2829,
0x3026_2A2B,
0x2C2D_2E2F,
0x3032_3031,
0x0000_0000,
])
);
}
#[test]
fn reset_smaller_payload_bytes() {
let mut message = Sysex7::<std::vec::Vec<u8>>::new();
message.set_payload((0u8..20u8).map(u7::new));
message.set_payload((0u8..10).map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xF7,
])
);
}
#[test]
fn reset_larger_payload_bytes() {
let mut message = Sysex7::<std::vec::Vec<u8>>::new();
message.set_payload((0u8..20u8).map(u7::new));
message.set_payload((0u8..30).map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0xF7,
])
);
}
#[test]
fn set_rubbish_payload_bytes() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<u8>>::new();
message.set_payload(RubbishPayloadIterator::new().map(u7::new));
assert_eq!(
message,
Sysex7(std::vec![
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0xF7,
])
);
}
#[test]
fn try_set_rubbish_payload_to_fixed_size_buffer() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<[u8; 52]>::new();
message
.try_set_payload(RubbishPayloadIterator::new().map(u7::new))
.expect("Shouldn't fail");
assert_eq!(
message,
Sysex7([
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0xF7,
])
);
}
#[test]
fn payload_bytes() {
assert_eq!(
std::vec![
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D,
],
Sysex7::try_from(
&[
0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0xF7,
][..]
)
.unwrap()
.payload()
.map(u8::from)
.collect::<std::vec::Vec<u8>>()
);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn payload_bytes_nth() {
let buffer = [
0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0xF7,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
let mut payload = message.payload();
assert_eq!(payload.nth(0), Some(u7::new(0x0)));
assert_eq!(payload.nth(4), Some(u7::new(0x5)));
assert_eq!(payload.nth(12), Some(u7::new(0x12)));
assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
assert_eq!(payload.nth(0), None);
}
#[test]
fn payload_bytes_nth_with_empty_packets() {
let buffer = [
0x3010_0000_u32,
0x0000_0000,
0x3021_0000,
0x0000_0000,
0x3022_0102,
0x0000_0000,
0x3020_0000,
0x0000_0000,
0x3020_0000,
0x0000_0000,
0x3023_0304,
0x0500_0000,
0x3024_0607,
0x0809_0000,
0x3025_0A0B,
0x0C0D_0E00,
0x3026_0F10,
0x1112_1314,
0x3025_1516,
0x1718_1900,
0x3034_1A1B,
0x1C1D_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
let mut payload = message.payload();
assert_eq!(payload.len(), 30);
assert_eq!(payload.next(), Some(u7::new(0x0)));
assert_eq!(payload.len(), 29);
assert_eq!(payload.nth(4), Some(u7::new(0x5)));
assert_eq!(payload.len(), 24);
assert_eq!(payload.nth(12), Some(u7::new(0x12)));
assert_eq!(payload.len(), 11);
assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
assert_eq!(payload.len(), 0);
assert_eq!(payload.next(), None);
assert_eq!(payload.len(), 0);
}
#[test]
fn payload_bytes_len() {
assert_eq!(
Sysex7::try_from(
&[
0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0xF7,
][..]
)
.unwrap()
.payload()
.len(),
30,
);
}
#[test]
fn payload_ump() {
assert_eq!(
Sysex7::try_from(
&[
0x3016_0001_u32,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
][..]
)
.unwrap()
.payload()
.map(u8::from)
.collect::<std::vec::Vec<u8>>(),
std::vec![
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D,
],
);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn payload_ump_nth() {
let buffer = [
0x3016_0001_u32,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
let mut payload = message.payload();
assert_eq!(payload.len(), 30);
assert_eq!(payload.nth(0), Some(u7::new(0x0)));
assert_eq!(payload.len(), 29);
assert_eq!(payload.nth(4), Some(u7::new(0x5)));
assert_eq!(payload.len(), 24);
assert_eq!(payload.nth(12), Some(u7::new(0x12)));
assert_eq!(payload.len(), 11);
assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
assert_eq!(payload.len(), 0);
assert_eq!(payload.nth(0), None);
assert_eq!(payload.len(), 0);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn payload_ump_nth_non_contiguous_oversized() {
let buffer = [
0x3010_0000_u32,
0x0000_0000,
0x3021_0000,
0x0000_0000,
0x3022_0102,
0x0000_0000,
0x3023_0304,
0x0500_0000,
0x3024_0607,
0x0809_0000,
0x3025_0A0B,
0x0C0D_0E00,
0x3026_0F10,
0x1112_1314,
0x3025_1516,
0x1718_1900,
0x3034_1A1B,
0x1C1D_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
let mut payload = message.payload();
assert_eq!(payload.len(), 30);
assert_eq!(payload.nth(0), Some(u7::new(0x0)));
assert_eq!(payload.len(), 29);
assert_eq!(payload.nth(4), Some(u7::new(0x5)));
assert_eq!(payload.len(), 24);
assert_eq!(payload.nth(12), Some(u7::new(0x12)));
assert_eq!(payload.len(), 11);
assert_eq!(payload.nth(10), Some(u7::new(0x1D)));
assert_eq!(payload.len(), 0);
assert_eq!(payload.nth(0), None);
assert_eq!(payload.len(), 0);
}
#[test]
fn from_bytes() {
let buffer = [
0xF0_u8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0xF7,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
assert_eq!(
Sysex7::<std::vec::Vec<u32>>::from_bytes(message),
Sysex7(std::vec![
0x3016_0001,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
])
);
}
#[test]
fn from_ump() {
let buffer = [
0x3016_0001_u32,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
assert_eq!(
Sysex7::<std::vec::Vec<u8>>::from_ump(message),
Sysex7(std::vec![
0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0xF7,
])
);
}
#[test]
fn set_payload_to_fixed_size_buffer_with_overflow() {
let mut message = Sysex7::<[u32; 8]>::new();
assert_eq!(
message.try_set_payload((0..30).map(u7::new)),
Err(crate::error::BufferOverflow)
);
}
#[test]
fn empty_payload_ump() {
assert_eq!(
Sysex7::<std::vec::Vec<u32>>::new()
.payload()
.collect::<std::vec::Vec<u7>>(),
std::vec![]
);
}
#[test]
fn packets() {
use crate::Packets;
let buffer = [
0x3016_0001_u32,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3036_1819,
0x1A1B_1C1D,
];
let message = Sysex7::try_from(&buffer[..]).unwrap();
let mut packets = message.packets();
assert_eq!(&*packets.next().unwrap(), &[0x3016_0001, 0x0203_0405,][..]);
assert_eq!(&*packets.next().unwrap(), &[0x3026_0607, 0x0809_0A0B,][..]);
assert_eq!(&*packets.next().unwrap(), &[0x3026_0C0D, 0x0E0F_1011,][..]);
assert_eq!(&*packets.next().unwrap(), &[0x3026_1213, 0x1415_1617,][..]);
assert_eq!(&*packets.next().unwrap(), &[0x3036_1819, 0x1A1B_1C1D,][..]);
assert_eq!(packets.next(), None);
}
#[test]
fn packets_empty() {
use crate::Packets;
let message = Sysex7::<[u32; 2]>::new();
let mut packets = message.packets();
assert_eq!(&*packets.next().unwrap(), &[0x3000_0000, 0x0][..]);
assert_eq!(packets.next(), None);
}
#[test]
fn empty_message_is_compact() {
assert!(is_compact(&Sysex7(std::vec![0x3000_0000_u32, 0x0000_0000])));
}
#[test]
fn message_with_two_empty_packets_is_not_compact() {
assert!(!is_compact(&Sysex7(std::vec![
0x3010_0000_u32,
0x0000_0000,
0x3030_0000,
0x0000_0000,
])));
}
#[test]
fn message_with_non_contiguous_payload_is_not_compact() {
assert!(!is_compact(&Sysex7(std::vec![
0x3010_0000_u32,
0x0000_0000,
0x3021_0000,
0x0000_0000,
0x3022_0102,
0x0000_0000,
0x3023_0304,
0x0500_0000,
0x3024_0607,
0x0809_0000,
0x3025_0A0B,
0x0C0D_0E00,
0x3026_0F10,
0x1112_1314,
0x3025_1516,
0x1718_1900,
0x3034_1A1B,
0x1C1D_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
])));
}
#[test]
fn message_with_empty_packets_is_not_compact() {
assert!(!is_compact(&Sysex7(std::vec![
0x3010_0000_u32,
0x0000_0000,
0x3021_0000,
0x0000_0000,
0x3022_0102,
0x0000_0000,
0x3020_0000,
0x0000_0000,
0x3020_0000,
0x0000_0000,
0x3023_0304,
0x0500_0000,
0x3024_0607,
0x0809_0000,
0x3025_0A0B,
0x0C0D_0E00,
0x3026_0F10,
0x1112_1314,
0x3025_1516,
0x1718_1900,
0x3034_1A1B,
0x1C1D_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
0x0000_0000,
])))
}
#[test]
fn large_message_with_contiguous_payload_is_compact() {
assert!(is_compact(&Sysex7(std::vec![
0x3016_0001_u32,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3026_1819,
0x1A1B_1C1D,
0x3026_1E1F,
0x2021_2223,
0x3026_2425,
0x2627_2829,
0x3026_2A2B,
0x2C2D_2E2F,
0x3032_3031,
0x0000_0000,
])));
}
#[test]
fn compact_a_complete_message_is_no_op() {
let mut message = Sysex7([0x3005_0102_u32, 0x0304_0500]);
compact(&mut message);
assert_eq!(message.data(), &[0x3005_0102_u32, 0x0304_0500,])
}
#[test]
fn message_of_two_empty_packets_compacts_down_to_one_empty_packet() {
let mut message = Sysex7([0x3010_0000_u32, 0x0000_0000, 0x3030_0000, 0x0000_0000]);
compact(&mut message);
assert_eq!(message.data(), &[0x3000_0000, 0x0000_0000]);
}
#[test]
fn message_with_non_contiguous_payload_compacts_down() {
let mut message = Sysex7(std::vec![
0x3010_0000_u32,
0x0000_0000,
0x3021_0000,
0x0000_0000,
0x3022_0102,
0x0000_0000,
0x3023_0304,
0x0500_0000,
0x3024_0607,
0x0809_0000,
0x3025_0A0B,
0x0C0D_0E00,
0x3026_0F10,
0x1112_1314,
0x3025_1516,
0x1718_1900,
0x3024_1A1B,
0x1C1D_0000,
0x3023_1E1F,
0x2000_0000,
0x3022_2122,
0x0000_0000,
0x3021_2300,
0x0000_0000,
0x3020_0000,
0x0000_0000,
0x3021_2400,
0x0000_0000,
0x3022_2526,
0x0000_0000,
0x3023_2728,
0x2900_0000,
0x3024_2A2B,
0x2C2D_0000,
0x3034_2E2F,
0x3031_0000,
]);
compact(&mut message);
assert_eq!(
message.data(),
&[
0x3016_0001,
0x0203_0405,
0x3026_0607,
0x0809_0A0B,
0x3026_0C0D,
0x0E0F_1011,
0x3026_1213,
0x1415_1617,
0x3026_1819,
0x1A1B_1C1D,
0x3026_1E1F,
0x2021_2223,
0x3026_2425,
0x2627_2829,
0x3026_2A2B,
0x2C2D_2E2F,
0x3032_3031,
0x0000_0000,
]
);
}
fn move_payload_tail_no_op<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.move_payload_tail(0, 0);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
(0u8..30u8).map(u7::new).collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn move_payload_tail_ump_no_op() {
move_payload_tail_no_op::<u32>();
}
#[test]
fn move_payload_tail_bytes_no_op() {
move_payload_tail_no_op::<u8>();
}
fn move_payload_tail_one_place<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.move_payload_tail(0, 1);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn move_payload_tail_ump_one_place() {
move_payload_tail_one_place::<u32>();
}
#[test]
fn move_payload_tail_bytes_one_place() {
move_payload_tail_one_place::<u8>();
}
fn move_payload_tail_ten_places<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.move_payload_tail(0, 10);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
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,
16, 17, 18, 19,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn move_payload_tail_ump_ten_places() {
move_payload_tail_ten_places::<u32>();
}
#[test]
fn move_payload_tail_bytes_ten_places() {
move_payload_tail_ten_places::<u8>();
}
fn move_payload_tail_ten_places_back<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.move_payload_tail(10, 0);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn move_payload_tail_ump_ten_places_back() {
move_payload_tail_ten_places_back::<u32>();
}
#[test]
fn move_payload_tail_bytes_ten_places_back() {
move_payload_tail_ten_places_back::<u8>();
}
fn insert_rubbish_payload_front<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 0);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_rubbish_payload_front_ump() {
insert_rubbish_payload_front::<u32>();
}
#[test]
fn insert_rubbish_payload_front_bytes() {
insert_rubbish_payload_front::<u8>();
}
fn insert_rubbish_payload_back<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 30);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_rubbish_payload_back_ump() {
insert_rubbish_payload_back::<u32>();
}
#[test]
fn insert_rubbish_payload_back_bytes() {
insert_rubbish_payload_back::<u8>();
}
fn insert_rubbish_payload_middle<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.insert_payload(RubbishPayloadIterator::new().map(ux::u7::new), 15);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
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,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_rubbish_payload_middle_ump() {
insert_rubbish_payload_middle::<u32>();
}
#[test]
fn insert_rubbish_payload_middle_bytes() {
insert_rubbish_payload_middle::<u8>();
}
fn set_bytes<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0u8..30u8).map(u7::new));
message.set_byte(ux::u7::new(0x7F), 4);
message.set_byte(ux::u7::new(0x7E), 8);
message.set_byte(ux::u7::new(0x7D), 12);
message.set_byte(ux::u7::new(0x7C), 16);
message.set_byte(ux::u7::new(0x7B), 17);
message.set_byte(ux::u7::new(0x7A), 21);
message.set_byte(ux::u7::new(0x79), 25);
message.set_byte(ux::u7::new(0x78), 29);
let payload = message.payload().collect::<std::vec::Vec<u7>>();
assert_eq!(payload[4], ux::u7::new(0x7F));
assert_eq!(payload[8], ux::u7::new(0x7E));
assert_eq!(payload[12], ux::u7::new(0x7D));
assert_eq!(payload[16], ux::u7::new(0x7C));
assert_eq!(payload[17], ux::u7::new(0x7B));
assert_eq!(payload[21], ux::u7::new(0x7A));
assert_eq!(payload[25], ux::u7::new(0x79));
assert_eq!(payload[29], ux::u7::new(0x78));
}
#[test]
fn set_bytes_ump() {
set_bytes::<u32>();
}
#[test]
fn set_bytes_bytes() {
set_bytes::<u8>();
}
fn insert_payload_front_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
let mut message = Sysex7::<[U; N]>::new();
message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
message
.try_insert_payload((0..20u8).map(u7::new), 0)
.unwrap();
let payload = message.payload().collect::<std::vec::Vec<u7>>();
assert_eq!(
payload,
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_payload_front_fixed_size_buffer_ump() {
insert_payload_front_fixed_size_buffer::<18, u32>();
}
#[test]
fn insert_payload_front_fixed_size_buffer_bytes() {
insert_payload_front_fixed_size_buffer::<52, u8>();
}
fn insert_payload_back_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
let mut message = Sysex7::<[U; N]>::new();
message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
message
.try_insert_payload((0..20u8).map(u7::new), 30)
.unwrap();
let payload = message.payload().collect::<std::vec::Vec<u7>>();
assert_eq!(
payload,
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_payload_back_fixed_size_buffer_ump() {
insert_payload_back_fixed_size_buffer::<18, u32>();
}
#[test]
fn insert_payload_back_fixed_size_buffer_bytes() {
insert_payload_back_fixed_size_buffer::<52, u8>();
}
fn insert_payload_middle_fixed_size_buffer<const N: usize, U: crate::buffer::Unit>() {
let mut message = Sysex7::<[U; N]>::new();
message.try_set_payload((0u8..30u8).map(u7::new)).unwrap();
message
.try_insert_payload((0..20u8).map(u7::new), 15)
.unwrap();
let payload = message.payload().collect::<std::vec::Vec<u7>>();
assert_eq!(
payload,
[
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,
11, 12, 13, 14, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29,
]
.iter()
.cloned()
.map(ux::u7::new)
.collect::<std::vec::Vec<u7>>()
);
}
#[test]
fn insert_payload_middle_fixed_size_buffer_ump() {
insert_payload_middle_fixed_size_buffer::<18, u32>();
}
#[test]
fn insert_payload_middle_fixed_size_buffer_bytes() {
insert_payload_middle_fixed_size_buffer::<52, u8>();
}
fn insert_payload_fixed_size_buffer_fail<const N: usize, U: crate::buffer::Unit>() {
let mut message = Sysex7::<[U; N]>::new();
message.try_set_payload((0u8..20).map(u7::new)).unwrap();
assert_eq!(
message.try_insert_payload((0u8..20).map(u7::new), 15),
Err(crate::error::BufferOverflow),
);
}
#[test]
fn insert_payload_fixed_size_buffer_fail_ump() {
insert_payload_fixed_size_buffer_fail::<13, u32>();
}
#[test]
fn insert_payload_fixed_size_buffer_fail_bytes() {
insert_payload_fixed_size_buffer_fail::<41, u8>();
}
fn append_byte<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
for i in 0u8..20 {
message.append_byte(u7::new(i));
}
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn append_byte_ump() {
append_byte::<u32>();
}
#[test]
fn append_byte_bytes() {
append_byte::<u8>();
}
fn append_payload<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
message.append_payload((0..20).map(u7::new));
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn append_payload_ump() {
append_payload::<u32>();
}
#[test]
fn append_payload_bytes() {
append_payload::<u8>();
}
fn splice_payload<U: crate::buffer::Unit>() {
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
message.splice_payload(core::iter::repeat_n(u7::new(0x7F), 30), 5..10);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn splice_payload_ump() {
splice_payload::<u32>();
}
#[test]
fn splice_payload_bytes() {
splice_payload::<u8>();
}
fn splice_rubbish_payload<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 7..16);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
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,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 17, 18, 19,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn splice_rubbish_payload_ump() {
splice_rubbish_payload::<u32>();
}
#[test]
fn splice_rubbish_payload_bytes() {
splice_rubbish_payload::<u8>();
}
fn splice_rubbish_payload_front<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 0..2);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn splice_rubbish_payload_front_ump() {
splice_rubbish_payload_front::<u32>();
}
#[test]
fn splice_rubbish_payload_front_bytes() {
splice_rubbish_payload_front::<u8>();
}
fn splice_rubbish_payload_end<U: crate::buffer::Unit>() {
use crate::detail::test_support::rubbish_payload_iterator::RubbishPayloadIterator;
let mut message = Sysex7::<std::vec::Vec<U>>::new();
message.set_payload((0..20).map(u7::new));
message.splice_payload(RubbishPayloadIterator::new().map(u7::new), 19..20);
assert_eq!(
message.payload().collect::<std::vec::Vec<u7>>(),
[
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,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49,
]
.iter()
.cloned()
.map(u7::new)
.collect::<std::vec::Vec<u7>>(),
);
}
#[test]
fn splice_rubbish_payload_end_ump() {
splice_rubbish_payload_end::<u32>();
}
#[test]
fn splice_rubbish_payload_end_bytes() {
splice_rubbish_payload_end::<u8>();
}
}