1use std::error::Error as StdError;
2use std::fmt;
3use std::io::Error as IoError;
4
5#[derive(Debug)]
6pub enum Kind {
7 SyncByte(u8),
8 Buf(usize, usize),
9 PESStartCode(u32),
10 SectionSyntaxIndicatorNotSet,
11 AnnexA2EmptyBuf,
12 AnnexA2UnsupportedEncoding,
13 AnnexA2Decode,
14 AnnexA2TableA3Unexpected(u8),
15 AnnexA2TableA4Buf(usize, usize),
16 AnnexA2TableA4Unexpected(u8),
17 AnnexCBuf(usize, usize),
18
19 Io(IoError),
20}
21
22pub struct Error(Kind);
23
24impl Error {
25 pub fn new(kind: Kind) -> Error {
26 Error(kind)
27 }
28}
29
30impl fmt::Display for Error {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 write!(f, "{:?}", self)
33 }
34}
35
36impl fmt::Debug for Error {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(
39 f,
40 r#"(:error ({:?}) (:txt "{}""#,
41 self.0,
42 self.description()
43 )?;
44
45 match self.0 {
46 Kind::SyncByte(b) => write!(f, " (:got 0x{:02X})", b)?,
47 Kind::Buf(actual, expected) => {
48 write!(f, " (:sz-actual {} :sz-expected {})", actual, expected)?
49 }
50 Kind::PESStartCode(actual) => write!(f, " (:actual 0x{:08X})", actual)?,
51
52 Kind::AnnexA2TableA3Unexpected(b) => write!(f, " (:got 0x{:02X})", b)?,
53 Kind::AnnexA2TableA4Buf(actual, expected) => {
54 write!(f, " (:sz-actual {} :sz-expected {})", actual, expected)?
55 }
56 Kind::AnnexA2TableA4Unexpected(b) => write!(f, " (:got 0x{:02X})", b)?,
57
58 Kind::AnnexCBuf(actual, expected) => {
59 write!(f, " (:sz-actual {} :sz-expected {})", actual, expected)?
60 }
61
62 _ => {}
63 }
64
65 write!(f, "))")
66 }
67}
68
69impl StdError for Error {
70 fn description(&self) -> &str {
71 match self.0 {
72 Kind::SyncByte(..) => "expected sync byte as first element",
73 Kind::Buf(..) => "buffer is too small, more data required",
74 Kind::PESStartCode(..) => "(pes) unexpected start code",
75 Kind::SectionSyntaxIndicatorNotSet => "(psi) section-syntax-indicator must be set",
76
77 Kind::AnnexA2UnsupportedEncoding => "(annex-a2) unsupported encoding",
78 Kind::AnnexA2Decode => "(annex-a2) decode error",
79 Kind::AnnexA2EmptyBuf => "(annex-a2 parse) got empty character buffer",
80 Kind::AnnexA2TableA3Unexpected(..) => "(annex-a2 table-a3 parse) unexpected value",
81 Kind::AnnexA2TableA4Buf(..) => {
82 "(annex-a2 table-a4 parse) buffer is too small, more data required"
83 }
84 Kind::AnnexA2TableA4Unexpected(..) => "(annex-a2 table-a4 parse) unexpected value",
85
86 Kind::AnnexCBuf(..) => "(annex-c parse) buffer is too small, more data required",
87
88 Kind::Io(ref err) => err.description(),
89 }
90 }
91
92 fn cause(&self) -> Option<&dyn StdError> {
93 match self.0 {
94 Kind::Io(ref err) => Some(err),
95 _ => None,
96 }
97 }
98}
99
100impl PartialEq for Error {
101 fn eq(&self, other: &Error) -> bool {
102 match (&self.0, &other.0) {
103 (Kind::SyncByte(a1), Kind::SyncByte(a2)) => a1 == a2,
104 (Kind::Buf(a1, b1), Kind::Buf(a2, b2)) => a1 == a2 && b1 == b2,
105 (Kind::PESStartCode(a1), Kind::PESStartCode(a2)) => a1 == a2,
106 (Kind::SectionSyntaxIndicatorNotSet, Kind::SectionSyntaxIndicatorNotSet) => true,
107 (Kind::AnnexA2EmptyBuf, Kind::AnnexA2EmptyBuf) => true,
108 (Kind::AnnexA2UnsupportedEncoding, Kind::AnnexA2UnsupportedEncoding) => true,
109 (Kind::AnnexA2Decode, Kind::AnnexA2Decode) => true,
110 (Kind::AnnexA2TableA3Unexpected(a1), Kind::AnnexA2TableA3Unexpected(a2)) => a1 == a2,
111 (Kind::AnnexA2TableA4Buf(a1, b1), Kind::AnnexA2TableA4Buf(a2, b2)) => {
112 a1 == a2 && b1 == b2
113 }
114 (Kind::AnnexA2TableA4Unexpected(a1), Kind::AnnexA2TableA4Unexpected(a2)) => a1 == a2,
115 (Kind::AnnexCBuf(a1, a2), Kind::AnnexCBuf(b1, b2)) => a1 == a2 && b1 == b2,
116 (Kind::Io(..), Kind::Io(..)) => true,
117 _ => false,
118 }
119 }
120}
121impl Eq for Error {}
122
123impl From<IoError> for Error {
124 fn from(err: IoError) -> Error {
125 Error::new(Kind::Io(err))
126 }
127}