1use crate::rcl;
4use num_derive::{FromPrimitive, ToPrimitive};
5use num_traits::FromPrimitive;
6use std::{
7 error::Error,
8 fmt::{self, Debug},
9};
10
11#[repr(u32)]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
13pub enum RCLError {
14 Error = rcl::RCL_RET_ERROR,
15 Timeout = rcl::RCL_RET_TIMEOUT,
16 BadAlloc = rcl::RCL_RET_BAD_ALLOC,
17 InvalidArgument = rcl::RCL_RET_INVALID_ARGUMENT,
18 Unsupported = rcl::RCL_RET_UNSUPPORTED,
19 AlreadyInit = rcl::RCL_RET_ALREADY_INIT,
20 NotInit = rcl::RCL_RET_NOT_INIT,
21 MismatchedRmwId = rcl::RCL_RET_MISMATCHED_RMW_ID,
22 TopicNameInvalid = rcl::RCL_RET_TOPIC_NAME_INVALID,
23 ServiceNameInvalid = rcl::RCL_RET_SERVICE_NAME_INVALID,
24 UnknownSubstitution = rcl::RCL_RET_UNKNOWN_SUBSTITUTION,
25 AlreadyShutdown = rcl::RCL_RET_ALREADY_SHUTDOWN,
26 NodeInvalid = rcl::RCL_RET_NODE_INVALID,
27 NodeInvalidName = rcl::RCL_RET_NODE_INVALID_NAME,
28 NodeInvalidNamespace = rcl::RCL_RET_NODE_INVALID_NAMESPACE,
29 NodeNameNonExistent = rcl::RCL_RET_NODE_NAME_NON_EXISTENT,
30 PublisherInvalid = rcl::RCL_RET_PUBLISHER_INVALID,
31 SubscriptionInvalid = rcl::RCL_RET_SUBSCRIPTION_INVALID,
32 SubscriptionTakeFailed = rcl::RCL_RET_SUBSCRIPTION_TAKE_FAILED,
33 ClientInvalid = rcl::RCL_RET_CLIENT_INVALID,
34 ClientTakeFailed = rcl::RCL_RET_CLIENT_TAKE_FAILED,
35 ServiceInvalid = rcl::RCL_RET_SERVICE_INVALID,
36 ServiceTakeFailed = rcl::RCL_RET_SERVICE_TAKE_FAILED,
37 TimerInvalid = rcl::RCL_RET_TIMER_INVALID,
38 TimerCanceled = rcl::RCL_RET_TIMER_CANCELED,
39 WaitSetInvalid = rcl::RCL_RET_WAIT_SET_INVALID,
40 WaitSetEmpty = rcl::RCL_RET_WAIT_SET_EMPTY,
41 WaitSetFull = rcl::RCL_RET_WAIT_SET_FULL,
42 InvalidRemapRule = rcl::RCL_RET_INVALID_REMAP_RULE,
43 WrongLexeme = rcl::RCL_RET_WRONG_LEXEME,
44 InvalidRosArgs = rcl::RCL_RET_INVALID_ROS_ARGS,
45 InvalidParamRule = rcl::RCL_RET_INVALID_PARAM_RULE,
46 InvalidLogLevelRule = rcl::RCL_RET_INVALID_LOG_LEVEL_RULE,
47 EventInvalid = rcl::RCL_RET_EVENT_INVALID,
48 EventTakeFailed = rcl::RCL_RET_EVENT_TAKE_FAILED,
49 LifecycleStateRegistered = rcl::RCL_RET_LIFECYCLE_STATE_REGISTERED,
50 LifecycleStateNotRegistered = rcl::RCL_RET_LIFECYCLE_STATE_NOT_REGISTERED,
51 InvalidRetVal = !0,
52}
53
54impl fmt::Display for RCLError {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "{:?} ({})", self, *self as u32)
57 }
58}
59
60impl Error for RCLError {}
61
62pub type RCLResult<T> = Result<T, RCLError>;
64
65pub type DynError = Box<dyn Error + Send + Sync + 'static>;
67
68pub(crate) fn ret_val_to_err(n: rcl::rcl_ret_t) -> RCLResult<()> {
72 let n = n as u32;
73 if n == rcl::RCL_RET_OK {
74 Ok(())
75 } else {
76 Err(FromPrimitive::from_u32(n).unwrap_or(RCLError::InvalidRetVal))
77 }
78}
79
80#[repr(u32)]
84#[derive(Debug, Clone, Copy, PartialEq, Eq)]
85pub enum RCLActionError {
86 NameInvalid,
87 GoalAccepted,
90 GoalRejected,
91 ClientInvalid,
92 ClientTakeFailed,
93 ServerInvalid,
94 ServerTakeFailed,
95 GoalHandleInvalid,
96 GoalEventInvalid,
97 RCLError(RCLError),
98 InvalidRetVal,
99}
100
101impl fmt::Display for RCLActionError {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(f, "{:?} ({})", self, Into::<u32>::into(*self))
104 }
105}
106
107impl Error for RCLActionError {}
108
109pub type RCLActionResult<T> = Result<T, RCLActionError>;
111
112pub(crate) fn action_ret_val_to_err(n: rcl::rcl_ret_t) -> RCLActionResult<()> {
113 match n as u32 {
114 rcl::RCL_RET_OK => Ok(()),
115 rcl::RCL_RET_ACTION_NAME_INVALID => Err(RCLActionError::NameInvalid),
116 rcl::RCL_RET_ACTION_GOAL_ACCEPTED => Err(RCLActionError::GoalAccepted),
117 rcl::RCL_RET_ACTION_GOAL_REJECTED => Err(RCLActionError::GoalRejected),
118 rcl::RCL_RET_ACTION_CLIENT_INVALID => Err(RCLActionError::ClientInvalid),
119 rcl::RCL_RET_ACTION_CLIENT_TAKE_FAILED => Err(RCLActionError::ClientTakeFailed),
120 rcl::RCL_RET_ACTION_SERVER_INVALID => Err(RCLActionError::ServerInvalid),
121 rcl::RCL_RET_ACTION_SERVER_TAKE_FAILED => Err(RCLActionError::ServerTakeFailed),
122 rcl::RCL_RET_ACTION_GOAL_HANDLE_INVALID => Err(RCLActionError::GoalHandleInvalid),
123 rcl::RCL_RET_ACTION_GOAL_EVENT_INVALID => Err(RCLActionError::GoalEventInvalid),
124
125 _ => ret_val_to_err(n).map_err(RCLActionError::RCLError),
126 }
127}
128
129impl From<RCLActionError> for u32 {
130 fn from(val: RCLActionError) -> Self {
131 match val {
132 RCLActionError::NameInvalid => rcl::RCL_RET_ACTION_NAME_INVALID,
133 RCLActionError::GoalAccepted => rcl::RCL_RET_ACTION_GOAL_ACCEPTED,
134 RCLActionError::GoalRejected => rcl::RCL_RET_ACTION_GOAL_REJECTED,
135 RCLActionError::ClientInvalid => rcl::RCL_RET_ACTION_CLIENT_INVALID,
136 RCLActionError::ClientTakeFailed => rcl::RCL_RET_ACTION_CLIENT_TAKE_FAILED,
137 RCLActionError::ServerInvalid => rcl::RCL_RET_ACTION_SERVER_INVALID,
138 RCLActionError::ServerTakeFailed => rcl::RCL_RET_ACTION_SERVER_TAKE_FAILED,
139 RCLActionError::GoalHandleInvalid => rcl::RCL_RET_ACTION_GOAL_HANDLE_INVALID,
140 RCLActionError::GoalEventInvalid => rcl::RCL_RET_ACTION_GOAL_EVENT_INVALID,
141 RCLActionError::RCLError(err) => err as u32,
142 RCLActionError::InvalidRetVal => !0,
143 }
144 }
145}
146
147impl From<RCLError> for RCLActionError {
148 fn from(err: RCLError) -> Self {
149 RCLActionError::RCLError(err)
150 }
151}
152
153impl std::fmt::Display for rcl::rcutils_error_string_t {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 let s = self.str_;
156 let inner: &[u8] = unsafe { std::slice::from_raw_parts(s.as_ptr() as *const u8, s.len()) };
157 let s = String::from_utf8(inner.to_vec()).unwrap();
158 write!(f, "{}", s)
159 }
160}
161
162impl Error for rcl::rcutils_error_string_t {}