Skip to content

Commit 3ae162e

Browse files
author
Ben Leadbetter
committed
chore: Merge branch 'release/0.6.0'
2 parents 10c5e74 + ab8bd82 commit 3ae162e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2366
-797
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# 0.5.4
2+
* feat: generate MIDI CI messages
3+
* strongly typed MIDI CI version
4+
* implement MIDI CI discovery
5+
* fix: fixes sysex next impl broken with 'empty' packets
6+
* fix: some clippy warnings
7+
* refactor!: ci is no longer a default feature
8+
* refactor!: rename `note` properties to `note_number`
9+
* refactor!: `pitch7_9` and `pitch7_25` used fixed number type
10+
* pull in `fixed` crate
11+
112
# 0.5.4
213
* ci: update remote repo url to midi2-dev
314

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "midi2"
3-
version = "0.5.4"
3+
version = "0.6.0"
44
description = "Ergonomic, versatile, strong types wrapping MIDI 2.0 message data."
55
edition = "2021"
66
readme = "README.md"
@@ -21,7 +21,8 @@ name = "midi2"
2121
path = "src/lib.rs"
2222

2323
[features]
24-
default = ["std", "ci", "channel-voice2"]
24+
default = ["std", "channel-voice2"]
25+
# wip
2526
ci = ["sysex7"]
2627
flex-data = []
2728
channel-voice1 = []
@@ -35,7 +36,8 @@ utility = []
3536

3637
[dependencies]
3738
derive_more = { version = "0.99.17", features = ["from"], default-features = false }
38-
midi2_proc = { version = "0.5.4", path = "midi2_proc" }
39+
fixed = "1.27.0"
40+
midi2_proc = { version = "0.6.0", path = "midi2_proc" }
3941
ux = "0.1.6"
4042

4143
[dev-dependencies]

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ use midi2::prelude::*;
2626
let mut note_on = channel_voice2::NoteOn::<[u32; 4]>::new();
2727
note_on.set_group(u4::new(0x8));
2828
note_on.set_channel(u4::new(0xA));
29-
note_on.set_note(u7::new(0x5E));
29+
note_on.set_note_number(u7::new(0x5E));
3030
note_on.set_velocity(0x6A14);
3131

3232
assert_eq!(note_on.group(), u4::new(0x8));
3333
assert_eq!(note_on.channel(), u4::new(0xA));
34-
assert_eq!(note_on.note(), u7::new(0x5E));
34+
assert_eq!(note_on.note_number(), u7::new(0x5E));
3535
assert_eq!(note_on.velocity(), 0x6A14);
3636

3737
// Messages wrap an underlying buffer of data which can be read as an
@@ -69,10 +69,10 @@ fn handle_message(buffer: &[u32]) {
6969
println!("Channel Voice2: channel: {}", m.channel());
7070
match m {
7171
channel_voice2::ChannelVoice2::NoteOn(m) => {
72-
println!("Note On! note: {}, velocity: {}", m.note(), m.velocity());
72+
println!("Note On! note: {}, velocity: {}", m.note_number(), m.velocity());
7373
}
7474
channel_voice2::ChannelVoice2::NoteOff(m) => {
75-
println!("Note Off! note: {}, velocity: {}", m.note(), m.velocity());
75+
println!("Note Off! note: {}, velocity: {}", m.note_number(), m.velocity());
7676
}
7777
_ => {}
7878
}
@@ -156,7 +156,7 @@ You'll want to setup midi2 without default features to compile
156156
without the `std` feature.
157157

158158
```toml
159-
midi2 = { version = "0.5.4", default-features = false, features = ["channel-voice2", "sysex7"], }
159+
midi2 = { version = "0.6.0", default-features = false, features = ["channel-voice2", "sysex7"], }
160160
```
161161

162162
### Generic Representation

examples/handling_messages.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@ fn handle_message(buffer: &[u32]) {
66
println!("Channel Voice2: channel: {}", m.channel());
77
match m {
88
channel_voice2::ChannelVoice2::NoteOn(m) => {
9-
println!("Note On! note: {}, velocity: {}", m.note(), m.velocity());
9+
println!(
10+
"Note On! note: {}, velocity: {}",
11+
m.note_number(),
12+
m.velocity()
13+
);
1014
}
1115
channel_voice2::ChannelVoice2::NoteOff(m) => {
12-
println!("Note Off! note: {}, velocity: {}", m.note(), m.velocity());
16+
println!(
17+
"Note Off! note: {}, velocity: {}",
18+
m.note_number(),
19+
m.velocity()
20+
);
1321
}
1422
_ => {}
1523
}
1624
}
25+
#[cfg(feature = "sysex7")]
1726
Ok(UmpMessage::Sysex7(m)) => {
1827
println!(
1928
"Sysex 7bit: payload: {:?}",

fuzz/fuzz_targets/sysex8_payload_roundtrip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fuzz_target!(|data: &[u8]| {
99

1010
// payload is unchanged
1111
let payload = message.payload().collect::<Vec<u8>>();
12-
assert_eq!(payload, data.iter().cloned().collect::<Vec<u8>>());
12+
assert_eq!(payload, data.to_vec());
1313

1414
// message is in a valid state
1515
let mut buffer = Vec::new();

midi2_proc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "midi2_proc"
33
description = "Internal procedural macro crate. Only intended for use with midi2"
4-
version = "0.5.4"
4+
version = "0.6.0"
55
edition = "2021"
66
readme = "README.md"
77
license = "MIT OR Apache-2.0"

midi2_proc/src/common.rs

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,50 @@ impl BufferGeneric {
3131
}
3232
}
3333

34+
pub fn has_attr(field: &syn::Field, id: &str) -> bool {
35+
field.attrs.iter().any(|attr| {
36+
let syn::Meta::Path(path) = &attr.meta else {
37+
return false;
38+
};
39+
path.segments
40+
.last()
41+
.iter()
42+
.any(|&segment| segment.ident == id)
43+
})
44+
}
45+
46+
pub fn meta_type(field: &syn::Field) -> syn::Type {
47+
field
48+
.attrs
49+
.iter()
50+
.filter_map(|attr| {
51+
use syn::Meta::*;
52+
match &attr.meta {
53+
List(list) => Some(list),
54+
_ => None,
55+
}
56+
})
57+
.find(|list| {
58+
list.path
59+
.segments
60+
.last()
61+
.iter()
62+
.any(|&segment| segment.ident == "property")
63+
})
64+
.map(|list| {
65+
list.parse_args::<syn::Type>()
66+
.expect("Arguments to property attribute should be a valid type")
67+
})
68+
.expect("fields must be annotated with the property attribute")
69+
}
70+
71+
pub fn is_unit_tuple(ty: &syn::Type) -> bool {
72+
match ty {
73+
syn::Type::Tuple(tup) => tup.elems.is_empty(),
74+
_ => false,
75+
}
76+
}
77+
3478
pub fn buffer_generic(generics: &syn::Generics) -> Option<BufferGeneric> {
3579
let type_param = |param: &syn::GenericParam| {
3680
if let syn::GenericParam::Type(type_param) = param {
@@ -46,41 +90,52 @@ pub fn buffer_generic(generics: &syn::Generics) -> Option<BufferGeneric> {
4690
None
4791
}
4892
};
49-
let buffer_bound = |id: &'static str| {
50-
move |bound: &syn::TraitBound| match bound.path.segments.last().as_ref() {
93+
let is_buffer_bound = |id: &'static str| {
94+
move |bound: syn::TraitBound| match bound.path.segments.last().as_ref() {
5195
Some(segment) => segment.ident == id,
5296
None => false,
5397
}
5498
};
5599
for param in generics.params.iter().filter_map(type_param) {
56-
if let Some(_) = param
100+
if param
57101
.bounds
58102
.iter()
59103
.filter_map(trait_bound)
60-
.find(buffer_bound("Ump"))
104+
.any(is_buffer_bound("Ump"))
61105
{
62106
return Some(BufferGeneric::Ump(param.clone()));
63107
};
64-
if let Some(_) = param
108+
if param
65109
.bounds
66110
.iter()
67111
.filter_map(trait_bound)
68-
.find(buffer_bound("Bytes"))
112+
.any(is_buffer_bound("Bytes"))
69113
{
70114
return Some(BufferGeneric::Bytes(param.clone()));
71115
};
72-
if let Some(_) = param
116+
if param
73117
.bounds
74118
.iter()
75119
.filter_map(trait_bound)
76-
.find(buffer_bound("Buffer"))
120+
.any(is_buffer_bound("Buffer"))
77121
{
78122
return Some(BufferGeneric::UmpOrBytes(param.clone()));
79123
};
80124
}
81125
None
82126
}
83127

128+
pub fn std_only_attribute(is_std_only: bool) -> TokenStream {
129+
if is_std_only {
130+
quote! {
131+
#[cfg(feature = "std")]
132+
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
133+
}
134+
} else {
135+
TokenStream::new()
136+
}
137+
}
138+
84139
pub fn rebuffer_generics(repr: Representation) -> TokenStream {
85140
match repr {
86141
Representation::Ump => quote! {
@@ -146,3 +201,18 @@ pub fn try_rebuffer_generics(repr: Representation) -> TokenStream {
146201
},
147202
}
148203
}
204+
205+
pub fn parse_via_args(input: syn::parse::ParseStream) -> syn::Type {
206+
let syn::ExprParen { expr, .. } = input
207+
.parse()
208+
.expect("Bracketed expression should follow size arg");
209+
210+
let syn::Expr::Path(path) = *expr else {
211+
panic!("Via argument should contain a path type");
212+
};
213+
214+
syn::Type::Path(syn::TypePath {
215+
qself: path.qself,
216+
path: path.path,
217+
})
218+
}

midi2_proc/src/derives.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,16 +375,20 @@ pub fn debug(item: TokenStream1) -> TokenStream1 {
375375
_ => panic!("Only enums and structs supported"),
376376
};
377377
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
378-
let buffer_id = common::buffer_generic(&generics)
378+
let buffer_id = common::buffer_generic(generics)
379379
.expect("Expected buffer generic")
380380
.ident();
381381
quote! {
382382
impl #impl_generics core::fmt::Debug for #ident #ty_generics #where_clause {
383383
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
384+
use crate::BufferAccess as BufferAccessDeriveDebug;
385+
384386
fmt.write_fmt(format_args!("{}([", stringify!(#ident)))?;
385387
match <<#buffer_id as crate::buffer::Buffer>::Unit as crate::buffer::UnitPrivate>::UNIT_ID {
386388
crate::buffer::UNIT_ID_U8 => {
387-
let buff = self.0.buffer();
389+
use crate::buffer::SpecialiseU8 as SpecialiseU8DeriveDebug;
390+
391+
let buff = self.buffer_access();
388392
let mut iter = buff.specialise_u8().iter().peekable();
389393
while let Some(v) = iter.next() {
390394
fmt.write_fmt(format_args!("{:#04X}", v))?;
@@ -394,7 +398,9 @@ pub fn debug(item: TokenStream1) -> TokenStream1 {
394398
}
395399
}
396400
crate::buffer::UNIT_ID_U32 => {
397-
let buff = self.0.buffer();
401+
use crate::buffer::SpecialiseU32 as SpecialiseU32DeriveDebug;
402+
403+
let buff = self.buffer_access();
398404
let mut iter = buff.specialise_u32().iter().peekable();
399405
while let Some(v) = iter.next() {
400406
fmt.write_fmt(format_args!("{:#010X}", v))?;

0 commit comments

Comments
 (0)