#![forbid(unsafe_code)]
use std::{error::Error as StdError, io};
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum SourceError {
#[error("network: {0}")]
Net(#[from] kithara_net::NetError),
#[error("storage: {0}")]
Storage(#[from] kithara_storage::StorageError),
#[error("invalid path: {0}")]
InvalidPath(String),
#[error("playlist parse: {0}")]
PlaylistParse(String),
#[error("variant not found: {0}")]
VariantNotFound(String),
#[error("segment not found: {0}")]
SegmentNotFound(String),
#[error("key processing: {0}")]
KeyProcessing(String),
#[error("invalid url: {0}")]
InvalidUrl(String),
#[error("cancelled")]
Cancelled,
#[error("timeout: {0}")]
Timeout(String),
#[error("wait_range budget exceeded")]
WaitBudgetExceeded,
#[error("format change not applicable to this source kind/state")]
FormatChangeNotApplicable,
#[error("io: {0}")]
Io(#[from] io::Error),
#[error("{0}")]
Other(Box<dyn StdError + Send + Sync>),
}
impl SourceError {
pub fn other<E>(err: E) -> Self
where
E: StdError + Send + Sync + 'static,
{
Self::Other(Box::new(err))
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum StreamError {
#[error("source error: {0}")]
Source(#[source] SourceError),
}
impl<E> From<E> for StreamError
where
E: Into<SourceError>,
{
fn from(err: E) -> Self {
Self::Source(err.into())
}
}
pub type StreamResult<T> = Result<T, StreamError>;
#[cfg(test)]
mod tests {
use std::io::{Error as IoError, ErrorKind};
use kithara_test_utils::kithara;
use super::*;
#[kithara::test]
fn test_source_error_display() {
let io_err = IoError::new(ErrorKind::NotFound, "file missing");
let err = StreamError::Source(SourceError::Io(io_err));
assert!(err.to_string().contains("file missing"));
}
#[kithara::test]
fn test_stream_error_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<StreamError>();
assert_send_sync::<SourceError>();
}
}