ftth_rsip/error/
mod.rs

1mod tokenizer_error;
2
3pub use tokenizer_error::TokenizerError;
4
5use std::{error::Error as StdError, fmt};
6
7/// The `Error` enum indicates that something went wrong
8///
9/// It has 6 variants:
10///
11/// * `MissingHeader` that a header that is expected to be found was completely missing.
12/// There are some headers that are required everywhere in SIP, like `From`, `To` etc.
13/// * `InvalidParam` means some header parser did not succeed, and the reason for it is
14/// a missing or invalid parameter. Inner `String` should have the nom verbose error about it.
15/// * `ParseError` indicates a general parsing error. Inner `String` should have the verbose nom error
16/// giving hints on what went wrong.
17/// * `TokenizeError` indicates a general tokenizer error. Inner `String` should have the verbose nom error
18/// giving hints on what went wrong. A Tokenizer just tries to break the `bytes` into
19/// parts/components of rsip structs, but never tries to parse/convert to a specific type.
20/// So if a tokenizer fails and you get this error, it means it couldn't even manage to break the
21/// SIP message in the correct breakpoints.
22/// * `Utf8Error` indicates that the `from_utf8` std method completely failed. At least you should
23/// get the information regarding which header had this issue.
24/// * `Unexpected` indicates any other error.
25///
26#[derive(Debug, Eq, PartialEq, Clone)]
27pub enum Error {
28    MissingHeader(String),
29    MissingParam(String),
30    InvalidParam(String),
31    ParseError(String),
32    TokenizeError(String),
33    Utf8Error(String),
34    Unexpected(String),
35}
36
37impl Error {
38    pub fn tokenizer<'a, S, T>(tuple: (S, T)) -> Self
39    where
40        S: Into<String>,
41        T: Into<&'a bstr::BStr>,
42    {
43        Self::TokenizeError(format!(
44            "failed to tokenize {}: {}",
45            tuple.0.into(),
46            tuple.1.into()
47        ))
48    }
49
50    pub fn missing_header(header: &'static str) -> Self {
51        Self::MissingHeader(header.into())
52    }
53
54    pub fn missing_param(header: &'static str) -> Self {
55        Self::MissingParam(header.into())
56    }
57}
58
59impl From<TokenizerError> for Error {
60    fn from(from: TokenizerError) -> Self {
61        Self::TokenizeError(from.context)
62    }
63}
64
65impl From<nom::Err<TokenizerError>> for Error {
66    fn from(from: nom::Err<TokenizerError>) -> Self {
67        match from {
68            nom::Err::Incomplete(_) => Self::Unexpected("incomplete parsing?".into()),
69            nom::Err::Error(e) => e.into(),
70            nom::Err::Failure(e) => e.into(),
71        }
72    }
73}
74
75impl fmt::Display for Error {
76    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        match self {
78            Self::MissingHeader(inner) => write!(f, "rsip error: missing header: {}", inner),
79            Self::MissingParam(inner) => write!(f, "rsip error: missing param: {}", inner),
80            Self::InvalidParam(inner) => write!(f, "rsip error: invalid header param: {}", inner),
81            Self::ParseError(inner) => write!(f, "rsip error: could not parse part: {}", inner),
82            Self::TokenizeError(inner) => write!(f, "Tokenizer error: {}", inner),
83            Self::Unexpected(inner) => write!(f, "rsip quite unexpected error: {}", inner),
84            Self::Utf8Error(inner) => write!(f, "rsip error: invalid utf8 ({})", inner),
85        }
86    }
87}
88
89impl StdError for Error {}
90
91impl From<std::str::Utf8Error> for Error {
92    fn from(error: std::str::Utf8Error) -> Self {
93        Self::Utf8Error(error.to_string())
94    }
95}
96
97impl From<std::num::ParseIntError> for Error {
98    fn from(error: std::num::ParseIntError) -> Self {
99        Self::ParseError(error.to_string())
100    }
101}