1#[cfg(feature = "serialize")]
6use serde::ser::{Serialize, SerializeStruct, Serializer};
7use std::error;
8use std::error::Error;
9use std::fmt;
10extern crate url;
11use address::AddressType;
12use std::num::ParseFloatError;
13use std::num::ParseIntError;
14
15#[derive(Debug, Clone)]
16pub enum SdpParserInternalError {
17 UnknownAddressType(String),
18 AddressTypeMismatch {
19 found: AddressType,
20 expected: AddressType,
21 },
22 Generic(String),
23 Unsupported(String),
24 Integer(ParseIntError),
25 Float(ParseFloatError),
26 Domain(url::ParseError),
27 IpAddress(std::net::AddrParseError),
28}
29
30const INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE: &str = "Unknown address type";
31const INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH: &str =
32 "Address is of a different type(1) than declared(2)";
33
34impl fmt::Display for SdpParserInternalError {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 match *self {
37 SdpParserInternalError::UnknownAddressType(ref unknown) => write!(
38 f,
39 "{INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE}: {unknown}"
40 ),
41 SdpParserInternalError::AddressTypeMismatch { found, expected } => write!(
42 f,
43 "{INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH}: {found}, {expected}"
44 ),
45 SdpParserInternalError::Generic(ref message) => write!(f, "Parsing error: {message}"),
46 SdpParserInternalError::Unsupported(ref message) => {
47 write!(f, "Unsupported parsing error: {message}")
48 }
49 SdpParserInternalError::Integer(ref error) => {
50 write!(f, "Integer parsing error: {error}")
51 }
52 SdpParserInternalError::Float(ref error) => write!(f, "Float parsing error: {error}"),
53 SdpParserInternalError::Domain(ref error) => {
54 write!(f, "Domain name parsing error: {error}")
55 }
56 SdpParserInternalError::IpAddress(ref error) => {
57 write!(f, "IP address parsing error: {error}")
58 }
59 }
60 }
61}
62
63impl Error for SdpParserInternalError {
64 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
65 match *self {
66 SdpParserInternalError::Integer(ref error) => Some(error),
67 SdpParserInternalError::Float(ref error) => Some(error),
68 SdpParserInternalError::Domain(ref error) => Some(error),
69 SdpParserInternalError::IpAddress(ref error) => Some(error),
70 _ => None,
72 }
73 }
74}
75
76#[derive(Debug, Clone)]
77pub enum SdpParserError {
78 Line {
79 error: SdpParserInternalError,
80 line: String,
81 line_number: usize,
82 },
83 Unsupported {
84 error: SdpParserInternalError,
85 line: String,
86 line_number: usize,
87 },
88 Sequence {
89 message: String,
90 line_number: usize,
91 },
92}
93
94#[cfg(feature = "serialize")]
95impl Serialize for SdpParserError {
96 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
97 where
98 S: Serializer,
99 {
100 let mut state = serializer.serialize_struct(
101 "error",
102 match self {
103 SdpParserError::Sequence { .. } => 3,
104 _ => 4,
105 },
106 )?;
107 match self {
108 SdpParserError::Line { error, line, .. } => {
109 state.serialize_field("type", "Line")?;
110 state.serialize_field("message", &format!("{error}"))?;
111 state.serialize_field("line", line)?
112 }
113 SdpParserError::Unsupported { error, line, .. } => {
114 state.serialize_field("type", "Unsupported")?;
115 state.serialize_field("message", &format!("{error}"))?;
116 state.serialize_field("line", line)?
117 }
118 SdpParserError::Sequence { message, .. } => {
119 state.serialize_field("type", "Sequence")?;
120 state.serialize_field("message", message)?;
121 }
122 };
123 state.serialize_field(
124 "line_number",
125 &match *self {
126 SdpParserError::Line { line_number, .. } => line_number,
127 SdpParserError::Unsupported { line_number, .. } => line_number,
128 SdpParserError::Sequence { line_number, .. } => line_number,
129 },
130 )?;
131 state.end()
132 }
133}
134
135impl fmt::Display for SdpParserError {
136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137 match self {
138 SdpParserError::Line {
139 error,
140 line,
141 line_number,
142 } => write!(f, "Line error: {error} in line({line_number}): {line}"),
143 SdpParserError::Unsupported {
144 error,
145 line,
146 line_number,
147 } => write!(f, "Unsupported: {error} in line({line_number}): {line}",),
148 SdpParserError::Sequence {
149 message,
150 line_number,
151 } => write!(f, "Sequence error in line({line_number}): {message}"),
152 }
153 }
154}
155
156impl Error for SdpParserError {
157 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
158 match self {
159 SdpParserError::Line { error, .. } | SdpParserError::Unsupported { error, .. } => {
160 Some(error)
161 }
162 _ => None,
164 }
165 }
166}
167
168impl From<ParseIntError> for SdpParserInternalError {
169 fn from(err: ParseIntError) -> SdpParserInternalError {
170 SdpParserInternalError::Integer(err)
171 }
172}
173
174impl From<url::ParseError> for SdpParserInternalError {
175 fn from(err: url::ParseError) -> SdpParserInternalError {
176 SdpParserInternalError::Domain(err)
177 }
178}
179
180impl From<std::net::AddrParseError> for SdpParserInternalError {
181 fn from(err: std::net::AddrParseError) -> SdpParserInternalError {
182 SdpParserInternalError::IpAddress(err)
183 }
184}
185
186impl From<ParseFloatError> for SdpParserInternalError {
187 fn from(err: ParseFloatError) -> SdpParserInternalError {
188 SdpParserInternalError::Float(err)
189 }
190}
191
192#[cfg(test)]
193#[path = "./error_tests.rs"]
194mod tests;