use std::ops::Deref;
use coremidi_sys::{
ItemCount, MIDIEndpointDispose, MIDIEndpointRef, MIDIGetDestination,
MIDIGetNumberOfDestinations,
};
use crate::endpoints::endpoint::Endpoint;
use crate::Object;
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct Destination {
pub(crate) endpoint: Endpoint,
}
impl Destination {
pub(crate) fn new(endpoint_ref: MIDIEndpointRef) -> Self {
Self {
endpoint: Endpoint::new(endpoint_ref),
}
}
pub fn from_index(index: usize) -> Option<Destination> {
let endpoint_ref = unsafe { MIDIGetDestination(index as ItemCount) };
match endpoint_ref {
0 => None,
_ => Some(Self::new(endpoint_ref)),
}
}
}
impl Clone for Destination {
fn clone(&self) -> Self {
Self::new(self.endpoint.object.0)
}
}
impl AsRef<Object> for Destination {
fn as_ref(&self) -> &Object {
&self.endpoint.object
}
}
impl AsRef<Endpoint> for Destination {
fn as_ref(&self) -> &Endpoint {
&self.endpoint
}
}
impl Deref for Destination {
type Target = Endpoint;
fn deref(&self) -> &Endpoint {
&self.endpoint
}
}
pub struct Destinations;
impl Destinations {
pub fn count() -> usize {
unsafe { MIDIGetNumberOfDestinations() as usize }
}
}
impl IntoIterator for Destinations {
type Item = Destination;
type IntoIter = DestinationsIterator;
fn into_iter(self) -> Self::IntoIter {
DestinationsIterator {
index: 0,
count: Self::count(),
}
}
}
pub struct DestinationsIterator {
index: usize,
count: usize,
}
impl Iterator for DestinationsIterator {
type Item = Destination;
fn next(&mut self) -> Option<Destination> {
if self.index < self.count {
let destination = Destination::from_index(self.index);
self.index += 1;
destination
} else {
None
}
}
}
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct VirtualDestination {
pub(crate) endpoint: Endpoint,
}
impl VirtualDestination {
pub(crate) fn new(endpoint_ref: MIDIEndpointRef) -> Self {
Self {
endpoint: Endpoint::new(endpoint_ref),
}
}
}
impl Deref for VirtualDestination {
type Target = Endpoint;
fn deref(&self) -> &Endpoint {
&self.endpoint
}
}
impl From<Object> for VirtualDestination {
fn from(object: Object) -> Self {
Self::new(object.0)
}
}
impl Drop for VirtualDestination {
fn drop(&mut self) {
unsafe { MIDIEndpointDispose(self.endpoint.object.0) };
}
}