rsbullet_core/
error.rs

1use std::ffi::NulError;
2use std::fmt::{Display, Formatter};
3use std::io;
4
5use robot_behavior::RobotException;
6
7/// Represents failures that can occur while interacting with the Bullet physics server.
8#[derive(Debug)]
9pub enum BulletError {
10    /// Attempted to connect but Bullet returned a null pointer.
11    NullPointer(&'static str),
12    /// Bullet reported that the physics server is not responsive.
13    ServerUnavailable(&'static str),
14    /// The command completed with an unexpected status code.
15    UnexpectedStatus {
16        expected: i32,
17        actual: i32,
18    },
19    /// A low-level FFI command returned an error code.
20    CommandFailed {
21        message: &'static str,
22        code: i32,
23    },
24    UnknownType(&'static str),
25    /// Converting Rust strings into C strings failed.
26    CString(NulError),
27}
28
29impl Display for BulletError {
30    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31        match self {
32            BulletError::NullPointer(msg)
33            | BulletError::ServerUnavailable(msg)
34            | BulletError::UnknownType(msg) => write!(f, "{msg}"),
35            BulletError::UnexpectedStatus { expected, actual } => write!(
36                f,
37                "Unexpected Bullet status. expected={expected} actual={actual}"
38            ),
39            BulletError::CommandFailed { message, code } => {
40                write!(f, "{message} (code={code})")
41            }
42            BulletError::CString(err) => err.fmt(f),
43        }
44    }
45}
46
47impl std::error::Error for BulletError {}
48
49impl From<NulError> for BulletError {
50    fn from(value: NulError) -> Self {
51        BulletError::CString(value)
52    }
53}
54
55pub type BulletResult<T> = Result<T, BulletError>;
56
57impl From<io::Error> for BulletError {
58    fn from(e: io::Error) -> Self {
59        BulletError::CommandFailed {
60            message: "IO Error occurred",
61            code: e.raw_os_error().unwrap_or(-1),
62        }
63    }
64}
65
66impl From<BulletError> for RobotException {
67    fn from(e: BulletError) -> Self {
68        RobotException::CommandException(e.to_string())
69    }
70}
71
72impl From<RobotException> for BulletError {
73    fn from(value: RobotException) -> Self {
74        BulletError::CommandFailed {
75            message: Box::leak(value.to_string().into_boxed_str()),
76            code: -1,
77        }
78    }
79}