Skip to content
Snippets Groups Projects
Select Git revision
  • outgoingmessagesviewer
  • main default protected
  • lyra-ipv4ll-backport
  • dev-smart-pointer-refactor-2
  • topics
  • qt6
  • dev-smart-pointer-refactor
  • gse-interface-dev
  • crash-report-dev
  • riccardo-dev
  • roccaraso2024
  • euroc2024
  • euroc2023
  • roccaraso2023
  • euroc-2021
15 results

SkywardHub.pro

Blame
  • error.rs 5.38 KiB
    use rustmex::{message::AdHoc, mxArray, FromMatlabError, MxArray};
    
    /// Type alias for the result of the serialbridge functions
    pub type SResult<T> = std::result::Result<T, Error>;
    
    /// Utility trait to map errors to `rustmex::Error` more easily
    pub trait MapMexError<T, E> {
        /// Map the error to an ad-hoc error with the given `id` and `msg`
        fn map_err_adhoc(self, id: &str, msg: &str) -> Result<T, rustmex::Error>;
        /// Map the error to the given crate Error
        fn mexerr(self, err: Error) -> Result<T, rustmex::Error>;
        /// Map the error to the given function that returns a crate Error
        fn map_mexerr<O>(self, err: O) -> Result<T, rustmex::Error>
        where
            O: FnOnce(E) -> Error;
    }
    
    impl<T, E> MapMexError<T, E> for Result<T, E> {
        fn map_err_adhoc(self, id: &str, msg: &str) -> Result<T, rustmex::Error> {
            Ok(self.map_err(|_| AdHoc(id, msg))?)
        }
    
        fn mexerr(self, err: Error) -> Result<T, rustmex::Error> {
            self.map_err(|_| err.to_mexerr())
        }
    
        fn map_mexerr<O>(self, err: O) -> Result<T, rustmex::Error>
        where
            O: FnOnce(E) -> Error,
        {
            self.map_err(|e| err(e).to_mexerr())
        }
    }
    
    impl<T> MapMexError<T, ()> for Option<T> {
        fn map_err_adhoc(self, id: &str, msg: &str) -> Result<T, rustmex::Error> {
            Ok(self.ok_or(AdHoc(id, msg))?)
        }
    
        fn mexerr(self, err: Error) -> Result<T, rustmex::Error> {
            self.ok_or_else(|| err.to_mexerr())
        }
    
        fn map_mexerr<O>(self, err: O) -> Result<T, rustmex::Error>
        where
            O: FnOnce(()) -> Error,
        {
            self.ok_or_else(|| err(()).to_mexerr())
        }
    }
    
    /// Error type for the serialbridge functions
    #[derive(Debug, thiserror::Error)]
    pub enum Error {
        #[error("Too many parameters passed")]
        TooManyParameters,
        #[error("Missing serial mode (first argument)")]
        MissingSerialMode,
        #[error("Missing port name (second argument)")]
        MissingPortName,
        #[error("Missing port path (third argument)")]
        MissingPortPath,
        #[error("Missing baudrate (fourth argument)")]
        MissingBaudrate,
        #[error("Missing read amount (second argument)")]
        MissingReadAmount,
        #[error("Missing write data (second argument)")]
        MissingWriteData,
        #[error("String contains invalid characters")]
        String(#[from] std::ffi::IntoStringError),
        #[error("Invalid Matlab type used, {0}")]
        InvalidMatlabType(String),
        #[error("Invalid serial mode (choose from 'Open', 'Close', 'Read', 'Write')")]
        InvalidMode,
        #[error("Invalid port name (2nd argument): {0}")]
        InvalidPortName(Box<Self>),
        #[error("Invalid port path (3rd argument): {0}")]
        InvalidPortPath(Box<Self>),
        #[error("Invalid baud rate (4th argument): {0}")]
        InvalidBaudrate(Box<Self>),
        #[error("Invalid read amount (2nd argument): {0}")]
        InvalidReadAmount(Box<Self>),
        #[error("Invalid write data (2nd argument): {0}")]
        InvalidWriteData(Box<Self>),
        #[error("Serial port error: {0}")]
        SerialPort(#[from] serialport::Error),
        #[error("I/O error: {0}")]
        IO(#[from] std::io::Error),
        #[error("Channel error: {0}")]
        Channel(#[from] std::sync::mpsc::SendError<Vec<u8>>),
        #[error("Parse error")]
        Parse,
        #[error("Matlab error: {0}")]
        Matlab(#[from] rustmex::FromMatlabError<MxArray>),
        #[error("{0}")]
        Rustmex(#[from] rustmex::Error),
        #[error("Return type cannot be assigned")]
        ReturnType,
        #[error("Serial port is not open")]
        SerialNotOpen,
    }
    
    impl Error {
        /// Get the error id (useful for `rustmex::Error` AdHoc Message construction)
        fn id(&self) -> &str {
            match self {
                Error::TooManyParameters => "serialbridge:invalid_input",
                Error::MissingSerialMode => "serialbridge:missing_input",
                Error::MissingPortName => "serialbridge:missing_input",
                Error::MissingPortPath => "serialbridge:missing_input",
                Error::MissingBaudrate => "serialbridge:missing_input",
                Error::MissingReadAmount => "serialbridge:missing_input",
                Error::MissingWriteData => "serialbridge:missing_input",
                Error::String(_) => "serialbridge:invalid_input",
                Error::InvalidMatlabType(_) => "serialbridge:invalid_input",
                Error::InvalidMode => "serialbridge:invalid_input",
                Error::InvalidPortName(_) => "serialbridge:invalid_input",
                Error::InvalidPortPath(_) => "serialbridge:invalid_input",
                Error::InvalidBaudrate(_) => "serialbridge:invalid_input",
                Error::InvalidReadAmount(_) => "serialbridge:invalid_input",
                Error::InvalidWriteData(_) => "serialbridge:invalid_input",
                Error::SerialPort(_) => "serialbridge:serial_error",
                Error::IO(_) => "serialbridge:serial_error",
                Error::Channel(_) => "serialbridge:channel_error",
                Error::Parse => "serialbridge:parse_error",
                Error::Matlab(_) => "serialbridge:matlab_error",
                Error::Rustmex(err) => err.id(),
                Error::ReturnType => "serialbridge:invalid_output",
                Error::SerialNotOpen => "serialbridge:serial_error",
            }
        }
    
        pub fn to_mexerr(&self) -> rustmex::Error {
            AdHoc(self.id(), self.to_string()).into()
        }
    }
    
    impl From<Error> for rustmex::Error {
        fn from(err: Error) -> Self {
            err.to_mexerr()
        }
    }
    
    impl From<FromMatlabError<&mxArray>> for Error {
        fn from(err: FromMatlabError<&mxArray>) -> Self {
            err.into()
        }
    }