#![deny(missing_docs)]
#![warn(clippy::all)]
#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use rodio::{cpal::FromSample, OutputStreamHandle, PlayError, Sample, Source};
#[cfg(feature = "future")]
use std::future::Future;
use std::{
io,
marker::PhantomData,
net::{TcpListener, TcpStream, UdpSocket},
os::unix::net::{UnixListener, UnixStream},
};
pub trait Receiver<O, E>
where
E: Sized,
{
fn accept(&self) -> Result<O, E>;
}
#[cfg(feature = "mut")]
pub trait MutReceiver<O, E>
where
E: Sized,
{
fn accept(&mut self) -> Result<O, E>;
}
#[cfg(feature = "future")]
pub trait FutureMutReceiver<O, E>
where
E: Sized,
{
fn accept(&mut self) -> impl Future<Output = Result<O, E>>;
}
impl<O, E, F> Receiver<O, E> for F
where
F: Fn() -> Result<O, E>,
E: Sized,
{
fn accept(&self) -> Result<O, E> {
self()
}
}
#[cfg(feature = "mut")]
impl<O, E, F> MutReceiver<O, E> for F
where
F: FnMut() -> Result<O, E>,
E: Sized,
{
fn accept(&mut self) -> Result<O, E> {
self()
}
}
#[cfg(feature = "mut")]
impl<O, E, F, L> FutureMutReceiver<O, E> for F
where
F: FnMut() -> L,
L: Future<Output = Result<O, E>>,
E: Sized,
{
fn accept(&mut self) -> impl Future<Output = Result<O, E>> {
self()
}
}
impl Receiver<(UnixStream, std::os::unix::net::SocketAddr), io::Error> for UnixListener {
fn accept(&self) -> Result<(UnixStream, std::os::unix::net::SocketAddr), std::io::Error> {
self.accept()
}
}
impl Receiver<(TcpStream, std::net::SocketAddr), io::Error> for TcpListener {
fn accept(&self) -> Result<(TcpStream, std::net::SocketAddr), std::io::Error> {
self.accept()
}
}
impl Receiver<[u8; u16::MAX as usize], io::Error> for UdpSocket {
fn accept(&self) -> Result<[u8; u16::MAX as usize], std::io::Error> {
let mut buf = [0; u16::MAX as usize];
self.recv(&mut buf)?;
Ok(buf)
}
}
pub trait AudioPlayer<S, O, E>
where
S: Source,
E: Sized,
<S as Iterator>::Item: Sample,
{
fn play(&self, source: S) -> Result<O, E>;
}
impl<S> AudioPlayer<S, (), PlayError> for OutputStreamHandle
where
S: Source + Send + 'static,
<S as Iterator>::Item: rodio::Sample,
f32: FromSample<<S as Iterator>::Item>,
{
fn play(&self, source: S) -> Result<(), PlayError> {
self.play_raw(source.convert_samples())
}
}
impl<S, O, E, F> AudioPlayer<S, O, E> for F
where
S: Source,
O: Sized,
E: Sized,
F: Fn(S) -> Result<O, E>,
<S as Iterator>::Item: Sample,
{
fn play(&self, source: S) -> Result<O, E> {
self(source)
}
}
pub trait StateBuzzer<S, R, O, E>
where
S: Source,
<S as Iterator>::Item: Sample,
R: Receiver<O, E>,
E: Sized,
{
fn buzz(&mut self, incoming: O) -> S;
}
pub trait Buzzer<S, R, O, E>
where
S: Source,
<S as Iterator>::Item: Sample,
R: Receiver<O, E>,
E: Sized,
{
fn buzz(&self, incoming: O) -> S;
}
#[cfg(feature = "mut")]
pub trait MutBuzzer<S, R, O, E>
where
S: Source,
<S as Iterator>::Item: Sample,
R: MutReceiver<O, E>,
E: Sized,
{
fn buzz(&self, incoming: O) -> S;
}
#[cfg(feature = "future")]
pub trait FutureMutBuzzer<H, E, L, P>
where
H: Source,
<H as Iterator>::Item: Sample,
E: FutureMutReceiver<L, P>,
P: Sized,
{
fn buzz(&self, incoming: L) -> H;
}
impl<S, R, O, E, F> Buzzer<S, R, O, E> for F
where
F: Fn(O) -> S,
S: Source,
<S as Iterator>::Item: Sample,
R: Receiver<O, E>,
E: Sized,
{
fn buzz(&self, incoming: O) -> S {
self(incoming)
}
}
#[cfg(feature = "mut")]
impl<S, R, O, E, F> MutBuzzer<S, R, O, E> for F
where
F: Fn(O) -> S,
S: Source,
<S as Iterator>::Item: Sample,
R: MutReceiver<O, E>,
E: Sized,
{
fn buzz(&self, incoming: O) -> S {
self(incoming)
}
}
#[cfg(feature = "future")]
impl<S, R, O, E, F> FutureMutBuzzer<S, R, O, E> for F
where
F: Fn(O) -> S,
S: Source,
<S as Iterator>::Item: Sample,
R: FutureMutReceiver<O, E>,
E: Sized,
{
fn buzz(&self, incoming: O) -> S {
self(incoming)
}
}
impl<S, R, O, E, F> StateBuzzer<S, R, O, E> for F
where
F: Fn(O) -> S,
S: Source,
<S as Iterator>::Item: Sample,
R: Receiver<O, E>,
E: Sized,
{
fn buzz(&mut self, incoming: O) -> S {
self(incoming)
}
}
pub struct Bup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source,
<S as Iterator>::Item: Sample,
R: Receiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
input: R,
output: &'a A,
#[allow(clippy::type_complexity)]
_phantom: (
PhantomData<S>,
PhantomData<O1>,
PhantomData<O2>,
PhantomData<E1>,
PhantomData<E2>,
),
}
#[cfg(feature = "mut")]
pub struct MutBup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source,
<S as Iterator>::Item: Sample,
R: MutReceiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
input: R,
output: &'a A,
#[allow(clippy::type_complexity)]
_phantom: (
PhantomData<S>,
PhantomData<O1>,
PhantomData<O2>,
PhantomData<E1>,
PhantomData<E2>,
),
}
#[cfg(feature = "future")]
pub struct FutureMutBup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source,
<S as Iterator>::Item: Sample,
R: FutureMutReceiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
input: R,
output: &'a A,
#[allow(clippy::type_complexity)]
_phantom: (
PhantomData<S>,
PhantomData<O1>,
PhantomData<O2>,
PhantomData<E1>,
PhantomData<E2>,
),
}
impl<'a, S, R, A, O1, O2, E1, E2> Bup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source + Send + 'static,
<S as Iterator>::Item: Sample,
f32: FromSample<<S as Iterator>::Item>,
R: Receiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
pub fn new(input: R, output: &'a A) -> Self {
Self {
input,
output,
_phantom: (
PhantomData,
PhantomData,
PhantomData,
PhantomData,
PhantomData,
),
}
}
pub fn activate_with_state<B: StateBuzzer<S, R, O1, E1>, E: Sized + From<E1> + From<E2>>(
&self,
mut buzzer: B,
) -> Result<(), E> {
loop {
self.output
.play(buzzer.buzz(self.input.accept().map_err(Into::<E>::into)?))?;
}
}
pub fn activate<B: Buzzer<S, R, O1, E1>, E: Sized + From<E1> + From<E2>>(
&self,
buzzer: B,
) -> Result<(), E> {
loop {
self.output
.play(buzzer.buzz(self.input.accept().map_err(Into::<E>::into)?))?;
}
}
}
#[cfg(feature = "mut")]
impl<'a, S, R, A, O1, O2, E1, E2> MutBup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source + Send + 'static,
<S as Iterator>::Item: Sample,
f32: FromSample<<S as Iterator>::Item>,
R: MutReceiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
pub fn new(input: R, output: &'a A) -> Self {
Self {
input,
output,
_phantom: (
PhantomData,
PhantomData,
PhantomData,
PhantomData,
PhantomData,
),
}
}
pub fn activate<B: MutBuzzer<S, R, O1, E1>, E: Sized + From<E1> + From<E2>>(
&mut self,
buzzer: B,
) -> Result<(), E> {
loop {
self.output
.play(buzzer.buzz(self.input.accept().map_err(Into::<E>::into)?))?;
}
}
}
#[cfg(feature = "future")]
impl<'a, S, R, A, O1, O2, E1, E2> FutureMutBup<'a, S, R, O1, E1, A, O2, E2>
where
S: Source + Send + 'static,
<S as Iterator>::Item: Sample,
f32: FromSample<<S as Iterator>::Item>,
R: FutureMutReceiver<O1, E1>,
A: AudioPlayer<S, O2, E2>,
E1: Sized,
E2: Sized,
{
pub fn new(input: R, output: &'a A) -> Self {
Self {
input,
output,
_phantom: (
PhantomData,
PhantomData,
PhantomData,
PhantomData,
PhantomData,
),
}
}
pub async fn activate<B: FutureMutBuzzer<S, R, O1, E1>, E: Sized + From<E1> + From<E2>>(
&mut self,
buzzer: B,
) -> Result<(), E> {
loop {
self.output
.play(buzzer.buzz(self.input.accept().await.map_err(Into::<E>::into)?))?;
}
}
}