use broadcast_common::impl_spec_display;
use thiserror::Error;
use super::action::{ResourceId, UtcId};
use crate::error::MpdError;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Failure {
Status(u16),
Transport,
Timeout,
TooLarge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum FailureKind {
Missing,
TooEarly,
Server,
Transport,
Invalid,
}
impl FailureKind {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Missing => "missing",
Self::TooEarly => "too_early",
Self::Server => "server",
Self::Transport => "transport",
Self::Invalid => "invalid",
}
}
}
impl_spec_display!(FailureKind);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum FailureClass {
Retry {
attempt: u32,
kind: FailureKind,
},
GiveUp,
NotYetAvailable {
retry_at_us: u64,
},
Expired,
SegmentSkipped,
EndTail,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Rejection {
NotMedia,
InitUndecodable,
DemuxFailed,
BadIndex,
WrongLength,
TooLarge,
NonFragmentedMp4,
}
impl Rejection {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::NotMedia => "not_media",
Self::InitUndecodable => "init_undecodable",
Self::DemuxFailed => "demux_failed",
Self::BadIndex => "bad_index",
Self::WrongLength => "wrong_length",
Self::TooLarge => "too_large",
Self::NonFragmentedMp4 => "non_fragmented_mp4",
}
}
}
impl_spec_display!(Rejection);
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum FatalKind {
ClockUnavailable,
MpdInvalid {
reason: &'static str,
},
Unsupported(crate::error::Unsupported),
UnsupportedAddressing {
reason: &'static str,
},
SegmentFetchFailed {
id: ResourceId,
status: Option<u16>,
},
InitFetchFailed {
id: ResourceId,
status: Option<u16>,
},
NonFragmentedMp4 {
id: ResourceId,
},
}
impl FatalKind {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::ClockUnavailable => "clock_unavailable",
Self::MpdInvalid { .. } => "mpd_invalid",
Self::Unsupported(u) => u.name(),
Self::UnsupportedAddressing { .. } => "unsupported_addressing",
Self::SegmentFetchFailed { .. } => "segment_fetch_failed",
Self::InitFetchFailed { .. } => "init_fetch_failed",
Self::NonFragmentedMp4 { .. } => "non_fragmented_mp4",
}
}
}
impl_spec_display!(FatalKind);
#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[non_exhaustive]
pub enum Error {
#[error("resource {id:?} was not requested")]
UnrequestedResource {
id: ResourceId,
},
#[error("resource {id:?} was delivered twice")]
DuplicateResource {
id: ResourceId,
},
#[error("no MPD is awaited")]
MpdNotAwaited,
#[error("MPD rejected: {0}")]
Mpd(MpdError),
#[error("UTC request {id:?} was not requested")]
UnrequestedUtc {
id: UtcId,
},
#[error("resource {id:?} rejected ({reason}): {class:?}")]
Rejected {
id: ResourceId,
reason: Rejection,
class: FailureClass,
},
#[error("the client has stopped")]
Stopped,
#[error("no such variant")]
NoSuchVariant,
#[error("no such audio set")]
NoSuchAudio,
#[error("the Representation cannot be switched now")]
NotSwitchable,
}
pub type Result<T> = core::result::Result<T, Error>;