1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
// Symphonia
// Copyright (c) 2019-2022 The Project Symphonia Developers.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! The `errors` module defines the common error type.
use std::error;
use std::fmt;
use std::io;
use std::result;
/// `SeekErrorKind` is a list of generic reasons why a seek may fail.
#[derive(Debug)]
pub enum SeekErrorKind {
/// The stream is not seekable at all.
Unseekable,
/// The stream can only be seeked forward.
ForwardOnly,
/// The timestamp to seek to is out of range.
OutOfRange,
/// The track ID provided is invalid.
InvalidTrack,
}
impl SeekErrorKind {
fn as_str(&self) -> &'static str {
match *self {
SeekErrorKind::Unseekable => "stream is not seekable",
SeekErrorKind::ForwardOnly => "stream can only be seeked forward",
SeekErrorKind::OutOfRange => "requested seek timestamp is out-of-range for stream",
SeekErrorKind::InvalidTrack => "invalid track id",
}
}
}
/// `Error` provides an enumeration of all possible errors reported by Symphonia.
#[derive(Debug)]
pub enum Error {
/// An IO error occured while reading, writing, or seeking the stream.
IoError(std::io::Error),
/// The stream contained malformed data and could not be decoded or demuxed.
DecodeError(&'static str),
/// The stream could not be seeked.
SeekError(SeekErrorKind),
/// An unsupported container or codec feature was encounted.
Unsupported(&'static str),
/// A default or user-defined limit was reached while decoding or demuxing the stream. Limits
/// are used to prevent denial-of-service attacks from malicious streams.
LimitError(&'static str),
/// The demuxer or decoder needs to be reset before continuing.
ResetRequired,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::IoError(ref err) => err.fmt(f),
Error::DecodeError(msg) => {
write!(f, "malformed stream: {}", msg)
}
Error::SeekError(ref kind) => {
write!(f, "seek error: {}", kind.as_str())
}
Error::Unsupported(feature) => {
write!(f, "unsupported feature: {}", feature)
}
Error::LimitError(constraint) => {
write!(f, "limit reached: {}", constraint)
}
Error::ResetRequired => {
write!(f, "decoder needs to be reset")
}
}
}
}
impl std::error::Error for Error {
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
Error::IoError(ref err) => Some(err),
Error::DecodeError(_) => None,
Error::SeekError(_) => None,
Error::Unsupported(_) => None,
Error::LimitError(_) => None,
Error::ResetRequired => None,
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::IoError(err)
}
}
pub type Result<T> = result::Result<T, Error>;
/// Convenience function to create a decode error.
pub fn decode_error<T>(desc: &'static str) -> Result<T> {
Err(Error::DecodeError(desc))
}
/// Convenience function to create a seek error.
pub fn seek_error<T>(kind: SeekErrorKind) -> Result<T> {
Err(Error::SeekError(kind))
}
/// Convenience function to create an unsupport feature error.
pub fn unsupported_error<T>(feature: &'static str) -> Result<T> {
Err(Error::Unsupported(feature))
}
/// Convenience function to create a limit error.
pub fn limit_error<T>(constraint: &'static str) -> Result<T> {
Err(Error::LimitError(constraint))
}
/// Convenience function to create a reset required error.
pub fn reset_error<T>() -> Result<T> {
Err(Error::ResetRequired)
}
/// Convenience function to create an end-of-stream error.
pub fn end_of_stream_error<T>() -> Result<T> {
Err(Error::IoError(io::Error::new(io::ErrorKind::UnexpectedEof, "end of stream")))
}