/* 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 http://mozilla.org/MPL/2.0/. */ #[cfg(feature = "serialize")] use serde::ser::{Serialize, SerializeStruct, Serializer}; use std::error; use std::error::Error; use std::fmt; extern crate url; use address::AddressType; use std::num::ParseFloatError; use std::num::ParseIntError; #[derive(Debug, Clone)] pub enum SdpParserInternalError { UnknownAddressType(String), AddressTypeMismatch { found: AddressType, expected: AddressType, }, Generic(String), Unsupported(String), Integer(ParseIntError), Float(ParseFloatError), Domain(url::ParseError), IpAddress(std::net::AddrParseError), } const INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE: &str = "Unknown address type"; const INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH: &str = "Address is of a different type(1) than declared(2)"; impl fmt::Display for SdpParserInternalError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { SdpParserInternalError::UnknownAddressType(ref unknown) => write!( f, "{}: {}", INTERNAL_ERROR_MESSAGE_UNKNOWN_ADDRESS_TYPE, unknown ), SdpParserInternalError::AddressTypeMismatch { found, expected } => write!( f, "{}: {}, {}", INTERNAL_ERROR_MESSAGE_ADDRESS_TYPE_MISMATCH, found, expected ), SdpParserInternalError::Generic(ref message) => write!(f, "Parsing error: {}", message), SdpParserInternalError::Unsupported(ref message) => { write!(f, "Unsupported parsing error: {}", message) } SdpParserInternalError::Integer(ref error) => { write!(f, "Integer parsing error: {}", error) } SdpParserInternalError::Float(ref error) => write!(f, "Float parsing error: {}", error), SdpParserInternalError::Domain(ref error) => { write!(f, "Domain name parsing error: {}", error) } SdpParserInternalError::IpAddress(ref error) => { write!(f, "IP address parsing error: {}", error) } } } } impl Error for SdpParserInternalError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match *self { SdpParserInternalError::Integer(ref error) => Some(error), SdpParserInternalError::Float(ref error) => Some(error), SdpParserInternalError::Domain(ref error) => Some(error), SdpParserInternalError::IpAddress(ref error) => Some(error), // Can't tell much more about our internal errors _ => None, } } } #[derive(Debug, Clone)] pub enum SdpParserError { Line { error: SdpParserInternalError, line: String, line_number: usize, }, Unsupported { error: SdpParserInternalError, line: String, line_number: usize, }, Sequence { message: String, line_number: usize, }, } #[cfg(feature = "serialize")] impl Serialize for SdpParserError { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut state = serializer.serialize_struct( "error", match *self { SdpParserError::Sequence { .. } => 3, _ => 4, }, )?; match *self { SdpParserError::Line { ref error, ref line, .. } => { state.serialize_field("type", "Line")?; state.serialize_field("message", &format!("{}", error))?; state.serialize_field("line", &line)? } SdpParserError::Unsupported { ref error, ref line, .. } => { state.serialize_field("type", "Unsupported")?; state.serialize_field("message", &format!("{}", error))?; state.serialize_field("line", &line)? } SdpParserError::Sequence { ref message, .. } => { state.serialize_field("type", "Sequence")?; state.serialize_field("message", &message)?; } }; state.serialize_field( "line_number", &match *self { SdpParserError::Line { line_number, .. } => line_number, SdpParserError::Unsupported { line_number, .. } => line_number, SdpParserError::Sequence { line_number, .. } => line_number, }, )?; state.end() } } impl fmt::Display for SdpParserError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { SdpParserError::Line { ref error, ref line, ref line_number, } => write!( f, "Line error: {} in line({}): {}", error, line_number, line ), SdpParserError::Unsupported { ref error, ref line, ref line_number, } => write!( f, "Unsupported: {} in line({}): {}", error, line_number, line ), SdpParserError::Sequence { ref message, ref line_number, } => write!(f, "Sequence error in line({}): {}", line_number, message), } } } impl Error for SdpParserError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match *self { SdpParserError::Line { ref error, .. } | SdpParserError::Unsupported { ref error, .. } => Some(error), // Can't tell much more about our internal errors _ => None, } } } impl From for SdpParserInternalError { fn from(err: ParseIntError) -> SdpParserInternalError { SdpParserInternalError::Integer(err) } } impl From for SdpParserInternalError { fn from(err: url::ParseError) -> SdpParserInternalError { SdpParserInternalError::Domain(err) } } impl From for SdpParserInternalError { fn from(err: std::net::AddrParseError) -> SdpParserInternalError { SdpParserInternalError::IpAddress(err) } } impl From for SdpParserInternalError { fn from(err: ParseFloatError) -> SdpParserInternalError { SdpParserInternalError::Float(err) } } #[cfg(test)] #[path = "./error_tests.rs"] mod tests;