use super::message::*; use crate::ws::Error as WsError; use aes_gcm::Error as CryptoError; use audiopus::Error as OpusError; use flume::SendError; use std::io::{Error as IoError, ErrorKind as IoErrorKind}; #[derive(Debug)] pub enum Recipient { AuxNetwork, Event, Mixer, #[cfg(feature = "receive")] UdpRx, } pub type Result = std::result::Result; #[derive(Debug)] #[non_exhaustive] pub enum Error { Crypto(CryptoError), #[cfg(any(feature = "receive", test))] /// Received an illegal voice packet on the voice UDP socket. IllegalVoicePacket, InterconnectFailure(Recipient), Io(IoError), Other, } impl Error { pub(crate) fn should_trigger_connect(&self) -> bool { match self { Error::InterconnectFailure(Recipient::AuxNetwork) => true, #[cfg(feature = "receive")] Error::InterconnectFailure(Recipient::UdpRx) => true, _ => false, } } pub(crate) fn should_trigger_interconnect_rebuild(&self) -> bool { matches!(self, Error::InterconnectFailure(Recipient::Event)) } // This prevents a `WouldBlock` from triggering a full reconnect, // instead simply dropping the packet. pub(crate) fn disarm_would_block(self) -> Result<()> { match self { Self::Io(i) if i.kind() == IoErrorKind::WouldBlock => Ok(()), e => Err(e), } } } impl From for Error { fn from(e: CryptoError) -> Self { Error::Crypto(e) } } impl From for Error { fn from(e: IoError) -> Error { Error::Io(e) } } impl From for Error { fn from(_: OpusError) -> Error { Error::Other } } impl From> for Error { fn from(_e: SendError) -> Error { Error::InterconnectFailure(Recipient::AuxNetwork) } } impl From> for Error { fn from(_e: SendError) -> Error { Error::InterconnectFailure(Recipient::Event) } } impl From> for Error { fn from(_e: SendError) -> Error { Error::InterconnectFailure(Recipient::Mixer) } } #[cfg(feature = "receive")] impl From> for Error { fn from(_e: SendError) -> Error { Error::InterconnectFailure(Recipient::UdpRx) } } impl From for Error { fn from(_: WsError) -> Error { Error::Other } }