Skip to content

Commit

Permalink
feat: rebuffer from exclusive to shared slice for aggregates
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Leadbetter authored and BenLeadbetter committed Feb 6, 2025
1 parent cb58c00 commit 05af663
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
69 changes: 68 additions & 1 deletion midi2_proc/src/derives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub fn try_from_ump(item: TokenStream1) -> TokenStream1 {
.into()
}

pub fn rebuffer_from(item: TokenStream1) -> TokenStream1 {
pub fn rebuffer_from_for_resizable_buffer(item: TokenStream1) -> TokenStream1 {
let input = parse_macro_input!(item as ItemEnum);
let ident = &input.ident;
let mut match_arms = TokenStream::new();
Expand Down Expand Up @@ -205,6 +205,73 @@ pub fn rebuffer_from(item: TokenStream1) -> TokenStream1 {
.into()
}

pub fn rebuffer_from_for_mut_slice_to_slice(item: TokenStream1) -> TokenStream1 {
use crate::common::Representation::*;

let input = parse_macro_input!(item as ItemEnum);
let ident = &input.ident;
let repr = match common::buffer_generic(&input.generics)
.expect("Message should have generic buffer type.")
{
common::BufferGeneric::Ump(_) => common::Representation::Ump,
common::BufferGeneric::Bytes(_) => common::Representation::Bytes,
common::BufferGeneric::UmpOrBytes(_) => common::Representation::UmpOrBytes,
};
let generics = if let UmpOrBytes = repr {
quote! { <'a, U: crate::buffer::Unit> }
} else {
quote! { <'a> }
};
let buffer = match repr {
Ump => quote! { [u32] },
Bytes => quote! { [u8] },
UmpOrBytes => quote! { [U] },
};
let mut match_arms = TokenStream::new();
for variant in &input.variants {
let variant_ident = &variant.ident;
let message_type = {
let syn::Fields::Unnamed(fields) = &variant.fields else {
panic!("Expected enum variant with unnamed fields");
};
let Some(syn::Field { ty, .. }) = fields.unnamed.last() else {
panic!("Expected an unnamed field in the enum variant");
};
let syn::Type::Path(syn::TypePath { path, .. }) = ty else {
panic!("Expected a 'path' type");
};
let mut path = path.clone();
path.segments.last_mut().unwrap().arguments = syn::PathArguments::None;
quote! {
#path::<&#buffer>
}
};

match_arms.extend(quote! {
#ident::#variant_ident(m) => #message_type::rebuffer_from(m).into(),
});
}

quote! {
impl #generics crate::traits::RebufferFrom<#ident<&'a mut #buffer>> for #ident<&'a #buffer>
{
fn rebuffer_from(other: #ident<&'a mut #buffer>) -> Self {
match other {
#match_arms
}
}
}
}
.into()
}

pub fn rebuffer_from(item: TokenStream1) -> TokenStream1 {
let mut ret = TokenStream1::new();
ret.extend(rebuffer_from_for_resizable_buffer(item.clone()));
ret.extend(rebuffer_from_for_mut_slice_to_slice(item.clone()));
ret
}

pub fn rebuffer_from_array(item: TokenStream1) -> TokenStream1 {
let input = parse_macro_input!(item as ItemEnum);
let ident = &input.ident;
Expand Down
17 changes: 17 additions & 0 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,23 @@ mod tests {
};
}

#[cfg(feature = "channel-voice1")]
#[test]
fn rebuffer_slice_from_mut_slice_impl() {
use crate::channel_voice1::ChannelPressure;
use crate::Data;
use crate::RebufferInto;

let mut buffer = [0x0_u32, 0x0];

let message_mut_slice: UmpMessage<&mut [u32]> =
ChannelPressure::try_new_with_buffer(&mut buffer[..])
.unwrap()
.into();
let message_slice: UmpMessage<&[u32]> = message_mut_slice.rebuffer_into();
assert_eq!(message_slice.data(), &[0x20D0_0000_u32][..]);
}

#[cfg(feature = "ump-stream")]
#[test]
fn ump_stream() {
Expand Down

0 comments on commit 05af663

Please sign in to comment.