Skip to content

Commit

Permalink
Fix object conversions (#47)
Browse files Browse the repository at this point in the history
Fix object conversions
  • Loading branch information
chris-zen authored Nov 18, 2023
1 parent 5f375ad commit 3a9f51a
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 190 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coremidi"
version = "0.7.1"
version = "0.8.0"
authors = ["Christian Perez-Llamas"]
description = "CoreMIDI library for Rust"
license = "MIT"
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The library is published into [crates.io](https://crates.io/crates/coremidi), so

```toml
[dependencies]
coremidi = "^0.7.0"
coremidi = "^0.8.0"
```

If you prefer to live in the edge ;-) you can use the master branch by including this instead:
Expand All @@ -68,8 +68,7 @@ git clone https://github.com/chris-zen/coremidi.git
cd coremidi
cargo build
cargo test
cargo doc
open target/doc/coremidi/index.html
cargo doc --open
```

# Examples
Expand Down
139 changes: 139 additions & 0 deletions src/any_object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use coremidi_sys::{MIDIObjectRef, MIDIObjectType};

use crate::{Destination, Device, Entity, Object, Source};

#[derive(Debug, PartialEq)]
pub enum AnyObject {
Other(Object),
Device(Device),
Entity(Entity),
Source(Source),
Destination(Destination),
ExternalDevice(Device),
ExternalEntity(Entity),
ExternalSource(Source),
ExternalDestination(Destination),
}

impl AnyObject {
pub(crate) fn create(object_type: MIDIObjectType, object_ref: MIDIObjectRef) -> Option<Self> {
match object_type {
coremidi_sys::kMIDIObjectType_Other => Some(Self::Other(Object(object_ref))),
coremidi_sys::kMIDIObjectType_Device => Some(Self::Device(Device::new(object_ref))),
coremidi_sys::kMIDIObjectType_Entity => Some(Self::Entity(Entity::new(object_ref))),
coremidi_sys::kMIDIObjectType_Source => Some(Self::Source(Source::new(object_ref))),
coremidi_sys::kMIDIObjectType_Destination => {
Some(Self::Destination(Destination::new(object_ref)))
}
coremidi_sys::kMIDIObjectType_ExternalDevice => {
Some(Self::ExternalDevice(Device::new(object_ref)))
}
coremidi_sys::kMIDIObjectType_ExternalEntity => {
Some(Self::ExternalEntity(Entity::new(object_ref)))
}
coremidi_sys::kMIDIObjectType_ExternalSource => {
Some(Self::ExternalSource(Source::new(object_ref)))
}
coremidi_sys::kMIDIObjectType_ExternalDestination => {
Some(Self::ExternalDestination(Destination::new(object_ref)))
}
_ => None,
}
}
}

impl AsRef<Object> for AnyObject {
fn as_ref(&self) -> &Object {
match self {
Self::Other(object) => object,
Self::Device(device) => &device.object,
Self::Entity(entity) => &entity.object,
Self::Source(source) => &source.object,
Self::Destination(destination) => &destination.object,
Self::ExternalDevice(device) => &device.object,
Self::ExternalEntity(entity) => &entity.object,
Self::ExternalSource(source) => &source.object,
Self::ExternalDestination(destination) => &destination.object,
}
}
}

#[cfg(test)]
mod tests {
use crate::any_object::AnyObject;
use crate::{Destination, Device, Entity, Object, Source};

#[test]
fn any_object_create() {
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_Other, 1),
Some(AnyObject::Other(Object(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_Device, 1),
Some(AnyObject::Device(Device::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_Entity, 1),
Some(AnyObject::Entity(Entity::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_Source, 1),
Some(AnyObject::Source(Source::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_Destination, 1),
Some(AnyObject::Destination(Destination::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_ExternalDevice, 1),
Some(AnyObject::ExternalDevice(Device::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_ExternalEntity, 1),
Some(AnyObject::ExternalEntity(Entity::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_ExternalSource, 1),
Some(AnyObject::ExternalSource(Source::new(1)))
);
assert_eq!(
AnyObject::create(coremidi_sys::kMIDIObjectType_ExternalDestination, 1),
Some(AnyObject::ExternalDestination(Destination::new(1)))
);
}

#[test]
fn any_object_as_ref() {
let expected_object = Object(1);
assert_eq!(AnyObject::Other(Object(1)).as_ref(), &expected_object);
assert_eq!(AnyObject::Device(Device::new(1)).as_ref(), &expected_object);
assert_eq!(AnyObject::Entity(Entity::new(1)).as_ref(), &expected_object);
assert_eq!(AnyObject::Source(Source::new(1)).as_ref(), &expected_object);
assert_eq!(
AnyObject::Destination(Destination::new(1)).as_ref(),
&expected_object
);
assert_eq!(
AnyObject::ExternalDevice(Device::new(1)).as_ref(),
&expected_object
);
assert_eq!(
AnyObject::ExternalEntity(Entity::new(1)).as_ref(),
&expected_object
);
assert_eq!(
AnyObject::ExternalSource(Source::new(1)).as_ref(),
&expected_object
);
assert_eq!(
AnyObject::ExternalDestination(Destination::new(1)).as_ref(),
&expected_object
);
}

#[test]
fn any_object_from_error() {
assert_eq!(AnyObject::create(0xffff_i32, 1), None);
}
}
24 changes: 12 additions & 12 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::object::Object;
///
/// A MIDI device or external device, containing entities.
///
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct Device {
pub(crate) object: Object,
}
Expand All @@ -20,22 +20,22 @@ impl Device {
}
}

impl Deref for Device {
type Target = Object;

fn deref(&self) -> &Object {
&self.object
impl Clone for Device {
fn clone(&self) -> Self {
Self::new(self.object.0)
}
}

impl From<Object> for Device {
fn from(object: Object) -> Self {
Self::new(object.0)
impl AsRef<Object> for Device {
fn as_ref(&self) -> &Object {
&self.object
}
}

impl From<Device> for Object {
fn from(device: Device) -> Self {
device.object
impl Deref for Device {
type Target = Object;

fn deref(&self) -> &Object {
&self.object
}
}
28 changes: 17 additions & 11 deletions src/endpoints/destinations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::Object;
/// println!("The source at index 0 has display name '{}'", source.display_name().unwrap());
/// ```
///
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct Destination {
pub(crate) endpoint: Endpoint,
}
Expand All @@ -41,23 +41,29 @@ impl Destination {
}
}

impl Deref for Destination {
type Target = Endpoint;
impl Clone for Destination {
fn clone(&self) -> Self {
Self::new(self.endpoint.object.0)
}
}

fn deref(&self) -> &Endpoint {
&self.endpoint
impl AsRef<Object> for Destination {
fn as_ref(&self) -> &Object {
&self.endpoint.object
}
}

impl From<Object> for Destination {
fn from(object: Object) -> Self {
Self::new(object.0)
impl AsRef<Endpoint> for Destination {
fn as_ref(&self) -> &Endpoint {
&self.endpoint
}
}

impl From<Destination> for Object {
fn from(destination: Destination) -> Self {
destination.endpoint.object
impl Deref for Destination {
type Target = Endpoint;

fn deref(&self) -> &Endpoint {
&self.endpoint
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::object::Object;
///
/// You don't need to create an endpoint directly, instead you can create system sources or virtual ones from a client.
///
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct Endpoint {
pub(crate) object: Object,
}
Expand Down
28 changes: 17 additions & 11 deletions src/endpoints/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::Object;
/// println!("The source at index 0 has display name '{}'", source.display_name().unwrap());
/// ```
///
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct Source {
pub(crate) endpoint: Endpoint,
}
Expand Down Expand Up @@ -50,23 +50,29 @@ impl Source {
}
}

impl Deref for Source {
type Target = Endpoint;
impl Clone for Source {
fn clone(&self) -> Self {
Self::new(self.endpoint.object.0)
}
}

fn deref(&self) -> &Endpoint {
&self.endpoint
impl AsRef<Object> for Source {
fn as_ref(&self) -> &Object {
&self.endpoint.object
}
}

impl From<Object> for Source {
fn from(object: Object) -> Self {
Self::new(object.0)
impl AsRef<Endpoint> for Source {
fn as_ref(&self) -> &Endpoint {
&self.endpoint
}
}

impl From<Source> for Object {
fn from(source: Source) -> Self {
source.endpoint.object
impl Deref for Source {
type Target = Endpoint;

fn deref(&self) -> &Endpoint {
&self.endpoint
}
}

Expand Down
24 changes: 12 additions & 12 deletions src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::object::Object;
///
/// An entity that a device owns and that contains endpoints.
///
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct Entity {
pub(crate) object: Object,
}
Expand All @@ -20,22 +20,22 @@ impl Entity {
}
}

impl Deref for Entity {
type Target = Object;

fn deref(&self) -> &Object {
&self.object
impl Clone for Entity {
fn clone(&self) -> Self {
Self::new(self.object.0)
}
}

impl From<Object> for Entity {
fn from(object: Object) -> Self {
Self::new(object.0)
impl AsRef<Object> for Entity {
fn as_ref(&self) -> &Object {
&self.object
}
}

impl From<Entity> for Object {
fn from(entity: Entity) -> Self {
entity.object
impl Deref for Entity {
type Target = Object;

fn deref(&self) -> &Object {
&self.object
}
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ For handling low level MIDI data you may look into:
*/

mod any_object;
mod client;
mod device;
mod endpoints;
Expand All @@ -63,7 +64,7 @@ pub use crate::endpoints::sources::{Source, Sources, VirtualSource};
pub use crate::entity::Entity;
pub use crate::events::{EventBuffer, EventList, EventListIter, EventPacket, Timestamp};
pub use crate::notifications::{AddedRemovedInfo, IoErrorInfo, Notification, PropertyChangedInfo};
pub use crate::object::{Object, ObjectType};
pub use crate::object::Object;
pub use crate::packets::{Packet, PacketBuffer, PacketList, PacketListIterator};
pub use crate::ports::{InputPort, InputPortWithContext, OutputPort};
pub use crate::properties::{
Expand Down
Loading

0 comments on commit 3a9f51a

Please sign in to comment.