Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/0.2.4 #11

Merged
merged 14 commits into from
May 8, 2024
25 changes: 25 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Rust

on:
push:
branches: [ "main", "develop" ]
pull_request:
branches: [ "main", "develop" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- uses: actions/checkout@v4
- name: Build
run: cargo build --verbose --all-features
- name: Run tests
run: cargo test --verbose --all-features
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 0.2.4
ci: add standard cargo github actions
docs: fix various typos
docs: online docs generated with all features enabled
fix: sysex7 / sysex8 payload iterator integration with jr headers
fix: sysex7 / sysex8 payload iterator panics when empty
test: add fuzzing target for sysex7 and sysex8 roundtrip

# 0.2.3
fix: handling messages example code
fix: default features include cv2 not cv1
Expand Down
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "midi2"
version = "0.2.3"
version = "0.2.4"
description = "Ergonomic, versatile, strong types wrapping MIDI 2.0 message data."
edition = "2021"
readme = "README.md"
Expand All @@ -13,6 +13,7 @@ repository = "https://github.com/BenLeadbetter/midi2.git"
[workspace]
members = [
"midi2_proc",
"fuzz",
]

[lib]
Expand All @@ -33,8 +34,11 @@ ump-stream = []

[dependencies]
derive_more = { version = "0.99.17", features = ["from"], default-features = false }
midi2_proc = { version = "0.2.3", path = "midi2_proc" }
midi2_proc = { version = "0.2.4", path = "midi2_proc" }
ux = "0.1.6"

[dev-dependencies]
pretty_assertions = "1.4.0"

[package.metadata.docs.rs]
all-features = true
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ You'll want to setup midi2 without default features to compile
without the `std` feature.

```toml
// Cargo.toml
midi2 = { version = "0.2.3", default-features = false, features = [<required-message-types>], }
midi2 = { version = "0.2.4", default-features = false, features = ["channel-voice2", "sysex7"], }
```

### Generic Representation
Expand Down Expand Up @@ -254,7 +253,7 @@ owned.set_jitter_reduction(Some(JitterReduction::Timestamp(0x1234)));
assert_eq!(owned.data(), &[0x0020_1234, 0x1AF3_4F00])
```

## Supports For Classical MIDI Byte Stream Messages
## Support For Classical MIDI Byte Stream Messages

Messages which can be represented in classical midi byte stream format are also supported.
To do this simply use a backing buffer over `u8` instead of `u32`! ✨🎩
Expand Down
4 changes: 4 additions & 0 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
corpus
artifacts
coverage
34 changes: 34 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "midi2-fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"

[dependencies.midi2]
path = ".."
default-features = false
features = [
"std",
"sysex8",
"sysex7",
]

[[bin]]
name = "sysex8_payload_roundtrip"
path = "./fuzz_targets/sysex8_payload_roundtrip.rs"
test = false
doc = false
bench = false

[[bin]]
name = "sysex7_payload_roundtrip"
path = "./fuzz_targets/sysex7_payload_roundtrip.rs"
test = false
doc = false
bench = false
22 changes: 22 additions & 0 deletions fuzz/fuzz_targets/sysex7_payload_roundtrip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use midi2::{prelude::*, sysex7::*};

fuzz_target!(|data: &[u8]| {
let to_u7 = |b: u8| u7::new(b & 0x7F);
let mut message = Sysex7::<Vec<u32>>::new();
message.set_payload(data.iter().cloned().map(to_u7));

// payload is unchanged
let payload = message.payload().collect::<Vec<u7>>();
assert_eq!(
payload,
data.iter().cloned().map(to_u7).collect::<Vec<u7>>()
);

// message is in a valid state
let mut buffer = Vec::new();
buffer.extend_from_slice(message.data());
let _ = Sysex7::try_from(&buffer[..]).expect("Valid data");
});
18 changes: 18 additions & 0 deletions fuzz/fuzz_targets/sysex8_payload_roundtrip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use midi2::{prelude::*, sysex8::*};

fuzz_target!(|data: &[u8]| {
let mut message = Sysex8::<Vec<u32>>::new();
message.set_payload(data.iter().cloned());

// payload is unchanged
let payload = message.payload().collect::<Vec<u8>>();
assert_eq!(payload, data.iter().cloned().collect::<Vec<u8>>());

// message is in a valid state
let mut buffer = Vec::new();
buffer.extend_from_slice(message.data());
let _ = Sysex8::try_from(&buffer[..]).expect("Valid data");
});
2 changes: 1 addition & 1 deletion midi2_proc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "midi2_proc"
description = "Internal procedural macro crate. Only intended for use with midi2"
version = "0.2.3"
version = "0.2.4"
edition = "2021"
readme = "README.md"
license = "MIT OR Apache-2.0"
Expand Down
12 changes: 6 additions & 6 deletions src/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Generic backing buffers for messages wrapper types.
//!
//!
//! All messages in midi2 are backed by a generic buffer type.
//!
//! A buffer can be any data type which returns a slice of `u32` or `u8`.
Expand All @@ -10,8 +10,8 @@
//! * `[U; SIZE] where U: Unit`
//! * `Vec<U> where U: Unit` (with the `std` feature enabled)
//!
//! The api of the message wrapper changes depending on the traits of the
//! backing buffer.
//! The api of the message wrapper changes depending on the traits of the
//! backing buffer.
//!
//! For example `&[U]` implements [Buffer]
//! but doesn't implement [BufferMut] so messages
Expand All @@ -29,7 +29,7 @@
//! assert_eq!(message.note(), u7::default());
//!
//! // error[E0277]: the trait bound `&[u32]: BufferMut` is not satisfied
//! message.set_note(u7::new(0x60));
//! message.set_note(u7::new(0x60));
//! ```
//!
//! `[U: SIZE]` buffers implement [BufferMut], but only
Expand All @@ -44,7 +44,7 @@
//! assert_eq!(message.try_set_payload(0..20), Ok(()));
//! ```
//! `Vec<U>` implements [BufferMut] and [BufferResize].
//! Messages backed with with such buffers have the most powerfull api.
//! Messages backed with with such buffers have the most powerful api.
//!
//! ```rust
//! use midi2::prelude::*;
Expand All @@ -59,7 +59,7 @@
//! possible to create a custom backing buffer.
//!
//! One potential fancy use case might be to create a non-allocating
//! resizable buffer which uses an area allocator.
//! resizable buffer which uses an arena allocator.

use crate::error::BufferOverflow;

Expand Down
8 changes: 8 additions & 0 deletions src/channel_voice2/note_on.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,12 @@ mod tests {
}),
);
}

#[test]
fn empty_jr_data() {
assert_eq!(
NoteOn([0x0, 0x4898_5E03, 0x6A14_E98A, 0x0, 0x0]).data(),
&[0x4898_5E03, 0x6A14_E98A],
);
}
}
10 changes: 10 additions & 0 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ impl<'a> core::convert::TryFrom<&'a [u32]> for UmpMessage<&'a [u32]> {
Eq,
)]
#[non_exhaustive]
#[cfg(any(
feature = "channel-voice1",
feature = "sysex7",
feature = "system-common"
))]
pub enum BytesMessage<B: crate::buffer::Bytes> {
#[cfg(feature = "channel-voice1")]
ChannelVoice1(crate::channel_voice1::ChannelVoice1<B>),
Expand All @@ -96,6 +101,11 @@ pub enum BytesMessage<B: crate::buffer::Bytes> {
SystemCommon(crate::system_common::SystemCommon<B>),
}

#[cfg(any(
feature = "channel-voice1",
feature = "sysex7",
feature = "system-common"
))]
impl<'a> core::convert::TryFrom<&'a [u8]> for BytesMessage<&'a [u8]> {
type Error = crate::error::Error;
fn try_from(buffer: &'a [u8]) -> Result<Self, Self::Error> {
Expand Down
2 changes: 1 addition & 1 deletion src/sysex7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ assert_eq!(
],
);

// Borrowed messages are immutable and their liftimes are
// Borrowed messages are immutable and their lifetimes are
// tied to the original buffer.
//
// To create an owned version use the `Rebuffer` traits.
Expand Down
Loading