webrtc_sdp/
error.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#[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            // Can't tell much more about our internal errors
71            _ => 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            // Can't tell much more about our internal errors
163            _ => 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;