2019-09-13 14:06:52 +00:00
|
|
|
use std::fmt;
|
2018-02-11 06:10:52 +00:00
|
|
|
|
2019-09-13 14:06:52 +00:00
|
|
|
use failure::{Backtrace, Context, Fail};
|
2018-02-11 06:10:52 +00:00
|
|
|
|
2019-09-13 14:06:52 +00:00
|
|
|
/// This crate specific `Result` type.
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
2019-10-03 14:23:27 +00:00
|
|
|
/// The [`ErrorKind`].
|
2019-09-15 08:40:45 +00:00
|
|
|
#[derive(Debug, Fail, Clone, PartialEq, Eq)]
|
2018-02-11 06:10:52 +00:00
|
|
|
pub enum ErrorKind {
|
2019-09-15 10:51:51 +00:00
|
|
|
#[fail(display = "ChronoParseError: {}", _0)]
|
|
|
|
/// An error from the [Chrono](chrono) crate.
|
|
|
|
ChronoParseError(String),
|
2019-09-21 10:11:36 +00:00
|
|
|
|
2019-09-13 14:06:52 +00:00
|
|
|
#[fail(display = "UnknownError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// An unknown error occured.
|
2019-09-13 14:06:52 +00:00
|
|
|
UnknownError(String),
|
|
|
|
|
|
|
|
#[fail(display = "A value is missing for the attribute {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// A required value is missing.
|
2019-09-13 14:06:52 +00:00
|
|
|
MissingValue(String),
|
|
|
|
|
|
|
|
#[fail(display = "Invalid Input")]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Error for anything.
|
2018-02-11 06:10:52 +00:00
|
|
|
InvalidInput,
|
2019-09-13 14:06:52 +00:00
|
|
|
|
|
|
|
#[fail(display = "ParseIntError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Failed to parse a String to int.
|
2019-09-13 14:06:52 +00:00
|
|
|
ParseIntError(String),
|
|
|
|
|
|
|
|
#[fail(display = "ParseFloatError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Failed to parse a String to float.
|
2019-09-13 14:06:52 +00:00
|
|
|
ParseFloatError(String),
|
|
|
|
|
|
|
|
#[fail(display = "MissingTag: Expected {} at the start of {:?}", tag, input)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// A tag is missing, that is required at the start of the input.
|
|
|
|
MissingTag {
|
|
|
|
/// The required tag.
|
|
|
|
tag: String,
|
|
|
|
/// The unparsed input data.
|
|
|
|
input: String,
|
|
|
|
},
|
2019-09-13 14:06:52 +00:00
|
|
|
|
|
|
|
#[fail(display = "CustomError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// A custom error.
|
2019-09-13 14:06:52 +00:00
|
|
|
Custom(String),
|
|
|
|
|
|
|
|
#[fail(display = "Unmatched Group: {:?}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Unmatched Group
|
2019-09-13 14:06:52 +00:00
|
|
|
UnmatchedGroup(String),
|
|
|
|
|
|
|
|
#[fail(display = "Unknown Protocol version: {:?}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Unknown m3u8 version. This library supports up to ProtocolVersion 7.
|
2019-09-13 14:06:52 +00:00
|
|
|
UnknownProtocolVersion(String),
|
|
|
|
|
2019-09-14 09:31:16 +00:00
|
|
|
#[fail(display = "IoError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// Some io error
|
2019-09-14 09:31:16 +00:00
|
|
|
Io(String),
|
|
|
|
|
2019-09-14 10:34:34 +00:00
|
|
|
#[fail(
|
|
|
|
display = "VersionError: required_version: {:?}, specified_version: {:?}",
|
|
|
|
_0, _1
|
|
|
|
)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// This error occurs, if there is a ProtocolVersion mismatch.
|
2019-09-14 10:34:34 +00:00
|
|
|
VersionError(String, String),
|
|
|
|
|
2019-09-14 11:26:16 +00:00
|
|
|
#[fail(display = "BuilderError: {}", _0)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// An Error from a Builder.
|
2019-09-14 11:26:16 +00:00
|
|
|
BuilderError(String),
|
|
|
|
|
2019-09-22 16:00:38 +00:00
|
|
|
#[fail(display = "Missing Attribute: {}", _0)]
|
|
|
|
/// An attribute is missing.
|
|
|
|
MissingAttribute(String),
|
|
|
|
|
2019-10-03 14:23:27 +00:00
|
|
|
#[fail(display = "Unexpected Attribute: {:?}", _0)]
|
|
|
|
/// An unexpected value.
|
|
|
|
UnexpectedAttribute(String),
|
|
|
|
|
2019-10-04 09:02:21 +00:00
|
|
|
#[fail(display = "Unexpected Tag: {:?}", _0)]
|
|
|
|
/// An unexpected tag.
|
|
|
|
UnexpectedTag(String),
|
|
|
|
|
2019-09-13 14:06:52 +00:00
|
|
|
/// Hints that destructuring should not be exhaustive.
|
|
|
|
///
|
|
|
|
/// This enum may grow additional variants, so this makes sure clients
|
|
|
|
/// don't count on exhaustive matching. (Otherwise, adding a new variant
|
|
|
|
/// could break existing code.)
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[fail(display = "Invalid error")]
|
|
|
|
__Nonexhaustive,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2019-09-14 19:08:35 +00:00
|
|
|
/// The Error type of this library.
|
2019-09-13 14:06:52 +00:00
|
|
|
pub struct Error {
|
|
|
|
inner: Context<ErrorKind>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Fail for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn cause(&self) -> Option<&dyn Fail> { self.inner.cause() }
|
2019-09-13 14:06:52 +00:00
|
|
|
|
2019-10-03 15:01:15 +00:00
|
|
|
fn backtrace(&self) -> Option<&Backtrace> { self.inner.backtrace() }
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.fmt(f) }
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<ErrorKind> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(kind: ErrorKind) -> Error { Error::from(Context::new(kind)) }
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Context<ErrorKind>> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(inner: Context<ErrorKind>) -> Error { Error { inner } }
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
pub(crate) fn missing_value<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::MissingValue(value.to_string()))
|
|
|
|
}
|
|
|
|
|
2019-10-03 14:23:27 +00:00
|
|
|
pub(crate) fn unexpected_attribute<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::UnexpectedAttribute(value.to_string()))
|
|
|
|
}
|
|
|
|
|
2019-10-04 09:02:21 +00:00
|
|
|
pub(crate) fn unexpected_tag<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::UnexpectedTag(value.to_string()))
|
|
|
|
}
|
|
|
|
|
2019-10-03 15:01:15 +00:00
|
|
|
pub(crate) fn invalid_input() -> Self { Self::from(ErrorKind::InvalidInput) }
|
2019-09-13 14:06:52 +00:00
|
|
|
|
|
|
|
pub(crate) fn parse_int_error<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::ParseIntError(value.to_string()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn parse_float_error<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::ParseFloatError(value.to_string()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn missing_tag<T, U>(tag: T, input: U) -> Self
|
|
|
|
where
|
|
|
|
T: ToString,
|
|
|
|
U: ToString,
|
|
|
|
{
|
|
|
|
Self::from(ErrorKind::MissingTag {
|
|
|
|
tag: tag.to_string(),
|
|
|
|
input: input.to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn unmatched_group<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::UnmatchedGroup(value.to_string()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn custom<T>(value: T) -> Self
|
|
|
|
where
|
|
|
|
T: fmt::Display,
|
|
|
|
{
|
|
|
|
Self::from(ErrorKind::Custom(value.to_string()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn unknown_protocol_version<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::UnknownProtocolVersion(value.to_string()))
|
|
|
|
}
|
2019-09-14 09:31:16 +00:00
|
|
|
|
2019-10-03 15:01:15 +00:00
|
|
|
pub(crate) fn io<T: ToString>(value: T) -> Self { Self::from(ErrorKind::Io(value.to_string())) }
|
2019-09-14 10:34:34 +00:00
|
|
|
|
|
|
|
pub(crate) fn required_version<T, U>(required_version: T, specified_version: U) -> Self
|
|
|
|
where
|
|
|
|
T: ToString,
|
|
|
|
U: ToString,
|
|
|
|
{
|
|
|
|
Self::from(ErrorKind::VersionError(
|
|
|
|
required_version.to_string(),
|
|
|
|
specified_version.to_string(),
|
|
|
|
))
|
|
|
|
}
|
2019-09-14 11:26:16 +00:00
|
|
|
|
|
|
|
pub(crate) fn builder_error<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::BuilderError(value.to_string()))
|
|
|
|
}
|
2019-09-15 09:25:41 +00:00
|
|
|
|
2019-09-15 10:51:51 +00:00
|
|
|
pub(crate) fn chrono<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::ChronoParseError(value.to_string()))
|
|
|
|
}
|
2019-09-22 16:00:38 +00:00
|
|
|
|
|
|
|
pub(crate) fn missing_attribute<T: ToString>(value: T) -> Self {
|
|
|
|
Self::from(ErrorKind::MissingAttribute(value.to_string()))
|
|
|
|
}
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
2019-09-14 19:08:35 +00:00
|
|
|
impl From<::std::num::ParseIntError> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(value: ::std::num::ParseIntError) -> Self { Error::parse_int_error(value) }
|
2019-09-13 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
2019-09-14 19:08:35 +00:00
|
|
|
impl From<::std::num::ParseFloatError> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(value: ::std::num::ParseFloatError) -> Self { Error::parse_float_error(value) }
|
2018-02-11 06:10:52 +00:00
|
|
|
}
|
2019-09-14 09:31:16 +00:00
|
|
|
|
2019-09-14 19:08:35 +00:00
|
|
|
impl From<::std::io::Error> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(value: ::std::io::Error) -> Self { Error::io(value) }
|
2019-09-14 09:31:16 +00:00
|
|
|
}
|
2019-09-15 09:25:41 +00:00
|
|
|
|
2019-09-15 10:51:51 +00:00
|
|
|
impl From<::chrono::ParseError> for Error {
|
2019-10-03 15:01:15 +00:00
|
|
|
fn from(value: ::chrono::ParseError) -> Self { Error::chrono(value) }
|
2019-09-15 10:51:51 +00:00
|
|
|
}
|
2019-09-22 18:33:40 +00:00
|
|
|
|
|
|
|
impl From<::strum::ParseError> for Error {
|
|
|
|
fn from(value: ::strum::ParseError) -> Self {
|
|
|
|
Error::custom(value) // TODO!
|
|
|
|
}
|
|
|
|
}
|
2019-10-05 11:15:42 +00:00
|
|
|
|
|
|
|
impl From<String> for Error {
|
|
|
|
fn from(value: String) -> Self { Error::custom(value) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<::core::convert::Infallible> for Error {
|
|
|
|
fn from(_: ::core::convert::Infallible) -> Self {
|
|
|
|
Error::custom("An Infallible error has been returned! (this should never happen!)")
|
|
|
|
}
|
|
|
|
}
|