Skip to content

Commit

Permalink
docs: add documentation to some central traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Leadbetter committed May 14, 2024
1 parent 2b60154 commit c70d859
Showing 1 changed file with 113 additions and 0 deletions.
113 changes: 113 additions & 0 deletions src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,95 @@
use crate::buffer::{Buffer, BufferMut, Ump};

/// View the wrapped data of the MIDI message as a slice of units.
///
/// A slice of [u32] for [Ump] backed messages.
///
/// ```rust
/// use midi2::{Data, channel_voice1::NoteOn};
///
/// let message = NoteOn::<[u32; 4]>::new();
///
/// assert_eq!(message.data(), &[0x2090_0000]);
/// ```
///
/// A slice of [u8] for [Bytes](crate::buffer::Bytes) backed messages.
///
/// ```rust
/// use midi2::{Data, channel_voice1::NoteOn};
///
/// let message = NoteOn::<[u8; 3]>::new();
///
/// assert_eq!(message.data(), &[0x90, 0x00, 0x00]);
/// ```
pub trait Data<B: Buffer> {
fn data(&self) -> &[B::Unit];
}

/// Read and mutate the MIDI 2.0 group field of a wrapped MIDI message.
///
/// ```rust
/// use midi2::{ux::u4, Grouped, Data, channel_voice2::NoteOn};
///
/// let mut message = NoteOn::<[u32; 4]>::new();
///
/// message.set_group(u4::new(0xA));
///
/// assert_eq!(message.group(), u4::new(0xA));
/// assert_eq!(message.data(), &[0x4A90_0000, 0x0000_0000]);
/// ```
pub trait Grouped<B: Ump> {
fn group(&self) -> crate::ux::u4;
fn set_group(&mut self, group: crate::ux::u4)
where
B: BufferMut;
}

/// Read and mutate the channel field of a wrapped MIDI message.
///
/// ```rust
/// use midi2::{ux::u4, Channeled, Data, channel_voice2::NoteOn};
///
/// let mut message = NoteOn::<[u32; 4]>::new();
///
/// message.set_channel(u4::new(0x5));
///
/// assert_eq!(message.channel(), u4::new(0x5));
/// assert_eq!(message.data(), &[0x4095_0000, 0x0000_0000]);
/// ```
pub trait Channeled<B: Buffer> {
fn channel(&self) -> crate::ux::u4;
fn set_channel(&mut self, channel: crate::ux::u4)
where
B: BufferMut;
}

/// Convert a generic message from one [buffer](crate::buffer) specialisation to another.
///
/// ```rust
/// use midi2::{RebufferFrom, Data, channel_voice1::NoteOn};
///
/// let borrowed: NoteOn<&[u32]> = NoteOn::try_from(&[0x2D9E_753D_u32][..]).expect("Valid data");
/// let owned = NoteOn::<[u32; 4]>::rebuffer_from(borrowed);
///
/// assert_eq!(owned.data(), &[0x2D9E_753D]);
/// ```
pub trait RebufferFrom<T>: Sized {
fn rebuffer_from(value: T) -> Self;
}

/// Convert a generic message into a different [buffer](crate::buffer) specialisation.
///
/// ```rust
/// use midi2::{RebufferInto, Data, channel_voice1::NoteOn};
///
/// let borrowed: NoteOn<&[u32]> = NoteOn::try_from(&[0x2D9E_753D_u32][..]).expect("Valid data");
/// let owned: NoteOn<[u32; 4]> = borrowed.rebuffer_into();
///
/// assert_eq!(owned.data(), &[0x2D9E_753D]);
/// ```
///
/// Note that this trait has a blanket implementation for all messages which implement
/// [RebufferFrom] (similar to the standard [core::convert::Into] trait)
pub trait RebufferInto<T>: Sized {
fn rebuffer_into(self) -> T;
}
Expand All @@ -35,10 +103,55 @@ where
}
}

/// Attempt to convert a generic message from one [buffer](crate::buffer) specialisation to another.
///
/// The conversion may fail with a [BufferOverflow](crate::error::BufferOverflow) error if the
/// target message representation does not fit all of the message data.
///
/// ```rust
/// use midi2::{TryRebufferFrom, sysex7::Sysex7};
///
/// let borrowed: Sysex7<&[u32]> = Sysex7::try_from(&[
/// 0x3016_0001,
/// 0x0203_0405,
/// 0x3035_0607,
/// 0x0809_0A00,
/// ][..]).expect("Valid data");
///
/// assert!(Sysex7::<[u32; 4]>::try_rebuffer_from(borrowed.clone()).is_ok());
/// assert!(Sysex7::<[u32; 2]>::try_rebuffer_from(borrowed.clone()).is_err());
/// ```
pub trait TryRebufferFrom<T>: Sized {
fn try_rebuffer_from(value: T) -> core::result::Result<Self, crate::error::BufferOverflow>;
}

/// Attempt to convert a generic message into a different [buffer](crate::buffer) specialisation.
///
/// The conversion may fail with a [BufferOverflow](crate::error::BufferOverflow) error if the
/// target message representation does not fit all of the message data.
///
/// ```rust
/// use midi2::{TryRebufferInto, sysex7::Sysex7, error::BufferOverflow};
///
/// let borrowed: Sysex7<&[u32]> = Sysex7::try_from(&[
/// 0x3016_0001,
/// 0x0203_0405,
/// 0x3035_0607,
/// 0x0809_0A00,
/// ][..]).expect("Valid data");
///
/// let arr4: Result<Sysex7<[u32; 4]>, BufferOverflow> = borrowed
/// .clone()
/// .try_rebuffer_into();
/// arr4.expect("Buffer is large enough");
///
/// let arr2: Result<Sysex7<[u32; 2]>, BufferOverflow> = borrowed
/// .clone()
/// .try_rebuffer_into();
/// arr2.expect_err("Buffer is too small");
/// ```
/// Note that this trait has a blanket implementation for all messages which implement
/// [TryRebufferFrom] (similar to the standard [core::convert::TryInto] trait)
pub trait TryRebufferInto<T>: Sized {
fn try_rebuffer_into(self) -> core::result::Result<T, crate::error::BufferOverflow>;
}
Expand Down

0 comments on commit c70d859

Please sign in to comment.