1pub type Result<T, E = Error> = std::result::Result<T, E>;
5
6#[non_exhaustive]
8#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
9pub enum Error {
10 NonSpecific,
12 Unsupported,
14 BadParameter,
16 PreconditionNotMet,
18 OutOfResources,
20 NotEnabled,
22 ImmutablePolicy,
24 InconsistentPolicy,
26 AlreadyDeleted,
28 Timeout,
30 NoData,
32 IllegalOperation,
34 NotAllowedBySecurity,
36}
37
38impl std::fmt::Display for Error {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 write!(
41 f,
42 "{}",
43 match self {
44 Error::NonSpecific => "non specific error occurred",
45 Error::Unsupported => "unsupported feature",
46 Error::BadParameter => "bad parameter provided",
47 Error::PreconditionNotMet => "precondition for operation not met",
48 Error::OutOfResources => "out of resources",
49 Error::NotEnabled => "feature not enabled",
50 Error::ImmutablePolicy => "attempted to modify immutable policy",
51 Error::InconsistentPolicy => "policy has inconsistent values",
52 Error::AlreadyDeleted => "entity already deleted",
53 Error::Timeout => "timeout reached",
54 Error::NoData => "data not provided",
55 Error::IllegalOperation => "operation is illegal",
56 Error::NotAllowedBySecurity => "insufficient credentials",
57 }
58 )
59 }
60}
61
62impl std::error::Error for Error {}
63
64pub(crate) trait IntoError<T>: Sized {
66 type Error;
67
68 fn into_error(self) -> Result<Self, Self::Error>;
69}
70
71impl IntoError<Error> for cyclonedds_sys::dds_return_t {
72 type Error = Error;
73
74 #[inline]
75 fn into_error(self) -> Result<Self, Self::Error> {
76 match self {
77 result if result >= 0 => Ok(result),
78 cyclonedds_sys::DDS_RETCODE_ERROR => Err(Self::Error::NonSpecific),
79 cyclonedds_sys::DDS_RETCODE_UNSUPPORTED => Err(Self::Error::Unsupported),
80 cyclonedds_sys::DDS_RETCODE_BAD_PARAMETER => Err(Self::Error::BadParameter),
81 cyclonedds_sys::DDS_RETCODE_PRECONDITION_NOT_MET => {
82 Err(Self::Error::PreconditionNotMet)
83 }
84 cyclonedds_sys::DDS_RETCODE_OUT_OF_RESOURCES => Err(Self::Error::OutOfResources),
85 cyclonedds_sys::DDS_RETCODE_NOT_ENABLED => Err(Self::Error::NotEnabled),
86 cyclonedds_sys::DDS_RETCODE_IMMUTABLE_POLICY => Err(Self::Error::ImmutablePolicy),
87 cyclonedds_sys::DDS_RETCODE_INCONSISTENT_POLICY => Err(Self::Error::InconsistentPolicy),
88 cyclonedds_sys::DDS_RETCODE_ALREADY_DELETED => Err(Self::Error::AlreadyDeleted),
89 cyclonedds_sys::DDS_RETCODE_TIMEOUT => Err(Self::Error::Timeout),
90 cyclonedds_sys::DDS_RETCODE_NO_DATA => Err(Self::Error::NoData),
91 cyclonedds_sys::DDS_RETCODE_ILLEGAL_OPERATION => Err(Self::Error::IllegalOperation),
92 cyclonedds_sys::DDS_RETCODE_NOT_ALLOWED_BY_SECURITY => {
93 Err(Self::Error::NotAllowedBySecurity)
94 }
95 _ => unreachable!(),
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_zero_is_success() {
106 let actual = 0.into_error();
107 let expected = Ok(0);
108 assert_eq!(actual, expected);
109 }
110
111 #[test]
112 fn test_positive_is_success() {
113 let actual = cyclonedds_sys::dds_return_t::MAX.into_error();
114 let expected = Ok(i32::MAX);
115 assert_eq!(actual, expected);
116 }
117
118 #[test]
119 fn test_error_mapping() {
120 let actual = cyclonedds_sys::DDS_RETCODE_ERROR.into_error();
121 let expected = Err(Error::NonSpecific);
122 assert_eq!(actual, expected);
123 assert_eq!(
124 format!("{}", actual.unwrap_err()),
125 "non specific error occurred"
126 );
127 let actual = cyclonedds_sys::DDS_RETCODE_UNSUPPORTED.into_error();
128 let expected = Err(Error::Unsupported);
129 assert_eq!(actual, expected);
130 assert_eq!(format!("{}", actual.unwrap_err()), "unsupported feature");
131 let actual = cyclonedds_sys::DDS_RETCODE_BAD_PARAMETER.into_error();
132 let expected = Err(Error::BadParameter);
133 assert_eq!(actual, expected);
134 assert_eq!(format!("{}", actual.unwrap_err()), "bad parameter provided");
135 let actual = cyclonedds_sys::DDS_RETCODE_PRECONDITION_NOT_MET.into_error();
136 let expected = Err(Error::PreconditionNotMet);
137 assert_eq!(actual, expected);
138 assert_eq!(
139 format!("{}", actual.unwrap_err()),
140 "precondition for operation not met"
141 );
142 let actual = cyclonedds_sys::DDS_RETCODE_OUT_OF_RESOURCES.into_error();
143 let expected = Err(Error::OutOfResources);
144 assert_eq!(actual, expected);
145 assert_eq!(format!("{}", actual.unwrap_err()), "out of resources");
146 let actual = cyclonedds_sys::DDS_RETCODE_NOT_ENABLED.into_error();
147 let expected = Err(Error::NotEnabled);
148 assert_eq!(actual, expected);
149 assert_eq!(format!("{}", actual.unwrap_err()), "feature not enabled");
150 let actual = cyclonedds_sys::DDS_RETCODE_IMMUTABLE_POLICY.into_error();
151 let expected = Err(Error::ImmutablePolicy);
152 assert_eq!(actual, expected);
153 assert_eq!(
154 format!("{}", actual.unwrap_err()),
155 "attempted to modify immutable policy"
156 );
157 let actual = cyclonedds_sys::DDS_RETCODE_INCONSISTENT_POLICY.into_error();
158 let expected = Err(Error::InconsistentPolicy);
159 assert_eq!(actual, expected);
160 assert_eq!(
161 format!("{}", actual.unwrap_err()),
162 "policy has inconsistent values"
163 );
164 let actual = cyclonedds_sys::DDS_RETCODE_ALREADY_DELETED.into_error();
165 let expected = Err(Error::AlreadyDeleted);
166 assert_eq!(actual, expected);
167 assert_eq!(format!("{}", actual.unwrap_err()), "entity already deleted");
168 let actual = cyclonedds_sys::DDS_RETCODE_TIMEOUT.into_error();
169 let expected = Err(Error::Timeout);
170 assert_eq!(actual, expected);
171 assert_eq!(format!("{}", actual.unwrap_err()), "timeout reached");
172 let actual = cyclonedds_sys::DDS_RETCODE_NO_DATA.into_error();
173 let expected = Err(Error::NoData);
174 assert_eq!(actual, expected);
175 assert_eq!(format!("{}", actual.unwrap_err()), "data not provided");
176 let actual = cyclonedds_sys::DDS_RETCODE_ILLEGAL_OPERATION.into_error();
177 let expected = Err(Error::IllegalOperation);
178 assert_eq!(actual, expected);
179 assert_eq!(format!("{}", actual.unwrap_err()), "operation is illegal");
180 let actual = cyclonedds_sys::DDS_RETCODE_NOT_ALLOWED_BY_SECURITY.into_error();
181 let expected = Err(Error::NotAllowedBySecurity);
182 assert_eq!(actual, expected);
183 assert_eq!(
184 format!("{}", actual.unwrap_err()),
185 "insufficient credentials"
186 );
187 }
188
189 #[test]
190 #[should_panic = "internal error: entered unreachable code"]
191 fn test_out_of_bounds_error_panics() {
192 let _ = cyclonedds_sys::dds_return_t::MIN.into_error();
193 }
194}