librespot/src/audio_backend/mod.rs

79 lines
2.7 KiB
Rust
Raw Normal View History

use std::io;
pub trait Open {
2016-07-06 09:54:46 +00:00
fn open(Option<&str>) -> Self;
}
pub trait Sink {
fn start(&self) -> io::Result<()>;
fn stop(&self) -> io::Result<()>;
fn write(&self, data: &[i16]) -> io::Result<()>;
}
/*
* Allow #[cfg] rules around elements of a list.
* Workaround until stmt_expr_attributes is stable.
*
* This generates 2^n declarations of the list, with every combination possible
*/
macro_rules! declare_backends {
(pub const $name:ident : $ty:ty = & [ $($tt:tt)* ];) => (
_declare_backends!($name ; $ty ; []; []; []; $($tt)*);
);
}
macro_rules! _declare_backends {
($name:ident ; $ty:ty ; [ $($yes:meta,)* ] ; [ $($no:meta,)* ] ; [ $($exprs:expr,)* ] ; #[cfg($m:meta)] $e:expr, $($rest:tt)* ) => (
_declare_backends!($name ; $ty ; [ $m, $($yes,)* ] ; [ $($no,)* ] ; [ $($exprs,)* $e, ] ; $($rest)*);
_declare_backends!($name ; $ty ; [ $($yes,)* ] ; [ $m, $($no,)* ] ; [ $($exprs,)* ] ; $($rest)*);
);
($name:ident ; $ty:ty ; [ $($yes:meta,)* ] ; [ $($no:meta,)* ] ; [ $($exprs:expr,)* ] ; $e:expr, $($rest:tt)*) => (
_declare_backends!($name ; $ty ; [ $($yes,)* ] ; [ $($no,)* ] ; [ $($exprs,)* $e, ] ; $($rest)*);
);
($name:ident ; $ty:ty ; [ $($yes:meta,)* ] ; [ $($no:meta,)* ] ; [ $($exprs:expr,)* ] ; #[cfg($m:meta)] $e:expr) => (
_declare_backends!($name ; $ty ; [ $m, $($yes,)* ] ; [ $($no,)* ] ; [ $($exprs,)* $e, ] ; );
_declare_backends!($name ; $ty ; [ $($yes,)* ] ; [ $m, $($no,)* ] ; [ $($exprs,)* ] ; );
);
($name:ident ; $ty:ty ; [ $($yes:meta,)* ] ; [ $($no:meta,)* ] ; [ $($exprs:expr,)* ] ; $e:expr ) => (
_declare_backends!($name ; $ty ; [ $($yes,)* ] ; [ $($no,)* ] ; [ $($exprs,)* $e, ] ; );
);
($name:ident ; $ty:ty ; [ $($yes:meta,)* ] ; [ $($no:meta,)* ] ; [ $($exprs:expr,)* ] ; ) => (
#[cfg(all($($yes,)* not(any($($no),*))))]
pub const $name : $ty = &[
$($exprs,)*
];
)
}
#[allow(dead_code)]
2016-07-06 09:54:46 +00:00
fn mk_sink<S: Sink + Open + 'static>(device: Option<&str>) -> Box<Sink> {
Box::new(S::open(device))
}
#[cfg(feature = "portaudio-backend")]
mod portaudio;
2016-05-04 08:56:23 +00:00
#[cfg(feature = "portaudio-backend")]
use self::portaudio::PortAudioSink;
2016-03-20 19:16:32 +00:00
#[cfg(feature = "pulseaudio-backend")]
mod pulseaudio;
2016-05-04 08:56:23 +00:00
#[cfg(feature = "pulseaudio-backend")]
use self::pulseaudio::PulseAudioSink;
2016-03-20 19:16:32 +00:00
declare_backends! {
2016-07-06 09:54:46 +00:00
pub const BACKENDS : &'static [
(&'static str,
&'static (Fn(Option<&str>) -> Box<Sink> + Sync + Send + 'static))
] = &[
#[cfg(feature = "portaudio-backend")]
2016-05-04 08:56:23 +00:00
("portaudio", &mk_sink::<PortAudioSink>),
2016-03-20 19:16:32 +00:00
#[cfg(feature = "pulseaudio-backend")]
2016-05-04 08:56:23 +00:00
("pulseaudio", &mk_sink::<PulseAudioSink>),
];
}