openthread/ot/
error.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use num::{FromPrimitive, ToPrimitive};
6use num_derive::{FromPrimitive, ToPrimitive};
7use openthread_sys::*;
8
9/// Type returned by OpenThread calls.
10pub type Result<T = (), E = Error> = std::result::Result<T, E>;
11
12/// Error type for when a given channel index is out of range.
13#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
14pub struct ChannelOutOfRange;
15
16impl std::fmt::Display for ChannelOutOfRange {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
18        std::fmt::Debug::fmt(self, f)
19    }
20}
21
22/// Error type for when a slice is not the correct size.
23#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
24pub struct WrongSize;
25
26impl std::fmt::Display for WrongSize {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
28        std::fmt::Debug::fmt(self, f)
29    }
30}
31
32/// Error type for when there is some sort of parsing error.
33#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
34pub struct ParseError;
35
36impl std::fmt::Display for ParseError {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
38        std::fmt::Debug::fmt(self, f)
39    }
40}
41
42/// Error type for when there are no buffers to allocate.
43#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
44pub struct NoBufs;
45
46impl std::fmt::Display for NoBufs {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
48        std::fmt::Debug::fmt(self, f)
49    }
50}
51
52impl From<NoBufs> for Error {
53    fn from(_: NoBufs) -> Self {
54        Error::NoBufs
55    }
56}
57
58/// Error type for when an IPv6 header is malformed or there are no buffers to allocate.
59#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
60pub struct MalformedOrNoBufs;
61
62impl std::fmt::Display for MalformedOrNoBufs {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
64        std::fmt::Debug::fmt(self, f)
65    }
66}
67
68/// Error type for when a system time cannot be converted to a timestamp.
69#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
70pub struct BadSystemTime;
71
72impl std::fmt::Display for BadSystemTime {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
74        std::fmt::Debug::fmt(self, f)
75    }
76}
77
78/// Error type for OpenThread calls. Functional equivalent of
79/// [`otsys::otError`](crate::otsys::otError).
80#[derive(
81    Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, FromPrimitive, ToPrimitive, thiserror::Error,
82)]
83#[allow(missing_docs)]
84pub enum Error {
85    Abort = OT_ERROR_ABORT as isize,
86    AddressFiltered = OT_ERROR_ADDRESS_FILTERED as isize,
87    AddressQuery = OT_ERROR_ADDRESS_QUERY as isize,
88    Already = OT_ERROR_ALREADY as isize,
89    Busy = OT_ERROR_BUSY as isize,
90    ChannelAccessFailure = OT_ERROR_CHANNEL_ACCESS_FAILURE as isize,
91    DestinationAddressFiltered = OT_ERROR_DESTINATION_ADDRESS_FILTERED as isize,
92    Detached = OT_ERROR_DETACHED as isize,
93    MessageDropped = OT_ERROR_DROP as isize,
94    Duplicated = OT_ERROR_DUPLICATED as isize,
95    Failed = OT_ERROR_FAILED as isize,
96    Fcs = OT_ERROR_FCS as isize,
97    Rejected = OT_ERROR_REJECTED as isize,
98    Generic = OT_ERROR_GENERIC as isize,
99    InvalidArgs = OT_ERROR_INVALID_ARGS as isize,
100    InvalidCommand = OT_ERROR_INVALID_COMMAND as isize,
101    InvalidState = OT_ERROR_INVALID_STATE as isize,
102    Ip6AddressCreationFailure = OT_ERROR_IP6_ADDRESS_CREATION_FAILURE as isize,
103    LinkMarginLow = OT_ERROR_LINK_MARGIN_LOW as isize,
104    NotCapable = OT_ERROR_NOT_CAPABLE as isize,
105    NotFound = OT_ERROR_NOT_FOUND as isize,
106    NotImplemented = OT_ERROR_NOT_IMPLEMENTED as isize,
107    NotLowpanDataFrame = OT_ERROR_NOT_LOWPAN_DATA_FRAME as isize,
108    None = OT_ERROR_NONE as isize,
109    NotTmf = OT_ERROR_NOT_TMF as isize,
110    NoAck = OT_ERROR_NO_ACK as isize,
111    NoAddress = OT_ERROR_NO_ADDRESS as isize,
112    NoBufs = OT_ERROR_NO_BUFS as isize,
113    NoFrameReceived = OT_ERROR_NO_FRAME_RECEIVED as isize,
114    NoRoute = OT_ERROR_NO_ROUTE as isize,
115    Parse = OT_ERROR_PARSE as isize,
116    Pending = OT_ERROR_PENDING as isize,
117    ReassemblyTimeout = OT_ERROR_REASSEMBLY_TIMEOUT as isize,
118    ResponseTimeout = OT_ERROR_RESPONSE_TIMEOUT as isize,
119    Security = OT_ERROR_SECURITY as isize,
120    UnknownNeighbor = OT_ERROR_UNKNOWN_NEIGHBOR as isize,
121}
122
123impl Error {
124    /// Converts this [`ot::Error`](crate::ot::Error) into a
125    /// [`otsys::otError`](crate::otsys::otError).
126    pub fn into_ot_error(self) -> otError {
127        self.to_u32().unwrap()
128    }
129
130    /// Converts this [`ot::Error`](crate::ot::Error) into a [`ot::Result`](crate::ot::Result),
131    /// mapping [`ot::Error::None`](crate::ot::Error::None) to [`Ok(())`] and any other error to
132    /// [`Err(x)`].
133    pub fn into_result(self) -> Result {
134        if self == Self::None {
135            Ok(())
136        } else {
137            Err(self)
138        }
139    }
140}
141
142impl std::fmt::Display for Error {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        std::fmt::Debug::fmt(self, f)
145    }
146}
147
148/// Trait for converting types into `otError` values.
149pub trait IntoOtError {
150    /// Converts this value into a
151    /// [`otsys::otError`](crate::otsys::otError).
152    fn into_ot_error(self) -> otError;
153}
154
155impl IntoOtError for Error {
156    fn into_ot_error(self) -> otError {
157        self.to_u32().unwrap()
158    }
159}
160
161impl IntoOtError for Result<(), Error> {
162    fn into_ot_error(self) -> otError {
163        self.err().unwrap_or(Error::None).into_ot_error()
164    }
165}
166
167impl From<Result<(), Error>> for Error {
168    fn from(result: Result<(), Error>) -> Self {
169        match result {
170            Ok(()) => Error::None,
171            Err(e) => e,
172        }
173    }
174}
175
176impl From<otError> for Error {
177    fn from(err: otError) -> Self {
178        Error::from_u32(err).unwrap_or_else(|| panic!("Unknown otError value: {err}"))
179    }
180}
181
182impl From<()> for Error {
183    fn from(_: ()) -> Self {
184        Error::None
185    }
186}
187
188impl From<Error> for otError {
189    fn from(err: Error) -> Self {
190        err.into_ot_error()
191    }
192}
193
194impl From<Error> for Result {
195    fn from(val: Error) -> Self {
196        val.into_result()
197    }
198}