Skip to main content

mavlink_core/
error.rs

1use crate::bytes;
2use core::{
3    convert::Infallible,
4    fmt::{Display, Formatter},
5};
6#[cfg(feature = "std")]
7use std::error::Error;
8
9/// Error while parsing a MAVLink message
10#[derive(Debug)]
11pub enum ParserError {
12    /// Enum value for this enum type does not exist
13    InvalidEnum { enum_type: &'static str, value: u64 },
14    /// Message ID does not exist in this message set
15    UnknownMessage { id: u32 },
16    /// Payload size is larger than the message definition permits.
17    InvalidPayloadSize {
18        id: u32,
19        maximum: usize,
20        actual: usize,
21    },
22    /// Errors that occurred in the bytes module.
23    BytesError(bytes::Error),
24}
25
26impl From<bytes::Error> for ParserError {
27    fn from(error: bytes::Error) -> Self {
28        Self::BytesError(error)
29    }
30}
31
32impl Display for ParserError {
33    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
34        match self {
35            Self::InvalidEnum { enum_type, value } => write!(
36                f,
37                "Invalid enum value for enum type {enum_type:?}, got {value:?}"
38            ),
39            Self::UnknownMessage { id } => write!(f, "Unknown message with ID {id:?}"),
40            Self::InvalidPayloadSize {
41                id,
42                maximum,
43                actual,
44            } => write!(
45                f,
46                "Message {id:?} has payload size {actual}, which exceeds the definition maximum of {maximum}"
47            ),
48            Self::BytesError(error) => write!(f, "{error}"),
49        }
50    }
51}
52
53#[cfg(feature = "std")]
54impl Error for ParserError {}
55
56/// Error while reading and parsing a MAVLink message
57#[derive(Debug)]
58pub enum MessageReadError {
59    /// IO Error while reading
60    #[cfg(feature = "std")]
61    Io(std::io::Error),
62    /// IO Error while reading
63    #[cfg(all(feature = "embedded", not(feature = "std")))]
64    Io,
65    /// Error while parsing
66    Parse(ParserError),
67}
68
69impl MessageReadError {
70    pub fn eof() -> Self {
71        #[cfg(feature = "std")]
72        return Self::Io(std::io::ErrorKind::UnexpectedEof.into());
73        #[cfg(all(feature = "embedded", not(feature = "std")))]
74        return Self::Io;
75    }
76}
77
78impl Display for MessageReadError {
79    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
80        match self {
81            #[cfg(feature = "std")]
82            Self::Io(e) => write!(f, "Failed to read message: {e:#?}"),
83            #[cfg(all(feature = "embedded", not(feature = "std")))]
84            Self::Io => write!(f, "Failed to read message"),
85            Self::Parse(e) => write!(f, "Failed to read message: {e:#?}"),
86        }
87    }
88}
89
90#[cfg(feature = "std")]
91impl Error for MessageReadError {}
92
93#[cfg(feature = "std")]
94impl From<std::io::Error> for MessageReadError {
95    fn from(e: std::io::Error) -> Self {
96        Self::Io(e)
97    }
98}
99
100impl From<ParserError> for MessageReadError {
101    fn from(e: ParserError) -> Self {
102        Self::Parse(e)
103    }
104}
105
106/// Error while encoding a MAVLink message.
107#[derive(Debug)]
108pub enum EncoderError {
109    /// Message ID does not exist in this dialect.
110    UnknownMessage { id: u32 },
111    /// Message belongs to a different dialect instance.
112    DialectMismatch { id: u32 },
113    /// Payload does not fit in the output buffer.
114    InvalidPayloadSize {
115        id: u32,
116        maximum: usize,
117        actual: usize,
118    },
119    /// MAVLink 1 only supports system IDs from 0 to 255
120    InvalidMAVLink1SystemId { id: u32 },
121}
122
123impl Display for EncoderError {
124    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
125        match self {
126            Self::UnknownMessage { id } => write!(f, "Unknown message with ID {id:?}"),
127            Self::DialectMismatch { id } => {
128                write!(f, "Message {id:?} belongs to a different dialect instance")
129            }
130            Self::InvalidPayloadSize {
131                id,
132                maximum,
133                actual,
134            } => write!(
135                f,
136                "Message {id:?} has payload size {actual}, which exceeds the buffer size of {maximum}"
137            ),
138            Self::InvalidMAVLink1SystemId { id } => {
139                write!(f, "System ID {id:?} is not supported by MAVLink 1")
140            }
141        }
142    }
143}
144
145#[cfg(feature = "std")]
146impl Error for EncoderError {}
147
148impl From<Infallible> for EncoderError {
149    fn from(error: Infallible) -> Self {
150        match error {}
151    }
152}
153
154/// Error while writing a MAVLink message
155#[derive(Debug)]
156pub enum MessageWriteError {
157    /// Message could not be encoded by its dialect.
158    Encode(EncoderError),
159    /// IO Error while writing
160    #[cfg(feature = "std")]
161    Io(std::io::Error),
162    /// IO Error while writing
163    #[cfg(all(feature = "embedded", not(feature = "std")))]
164    Io,
165    /// Message does not support MAVLink 1
166    MAVLink2Only,
167}
168
169impl Display for MessageWriteError {
170    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
171        match self {
172            Self::Encode(e) => write!(f, "Failed to encode message: {e}"),
173            #[cfg(feature = "std")]
174            Self::Io(e) => write!(f, "Failed to write message: {e:#?}"),
175            #[cfg(all(feature = "embedded", not(feature = "std")))]
176            Self::Io => write!(f, "Failed to write message"),
177            Self::MAVLink2Only => write!(f, "Message is not supported in MAVLink 1"),
178        }
179    }
180}
181
182#[cfg(feature = "std")]
183impl Error for MessageWriteError {}
184
185#[cfg(feature = "std")]
186impl From<std::io::Error> for MessageWriteError {
187    fn from(e: std::io::Error) -> Self {
188        Self::Io(e)
189    }
190}
191
192impl From<EncoderError> for MessageWriteError {
193    fn from(e: EncoderError) -> Self {
194        Self::Encode(e)
195    }
196}