Skip to content
Snippets Groups Projects
Commit 5fac5c8d authored by Federico Lolli's avatar Federico Lolli
Browse files

building main

parent 6d273aa4
No related branches found
No related tags found
No related merge requests found
use rustmex::{message::AdHoc, mxArray, FromMatlabError};
pub trait MapMexError<T> {
fn map_err_adhoc(self, id: &str, msg: &str) -> Result<T, rustmex::Error>;
fn mexerr(self, err: Error) -> Result<T, rustmex::Error>;
}
impl<T, E> MapMexError<T> 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())
}
}
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())
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Missing serial mode (first argument)")]
MissingSerialMode,
#[error("Missing port name (second argument)")]
MissingPortName,
#[error("Missing baudrate (third argument)")]
MissingBaudrate,
#[error("String contains invalid characters")]
String(#[from] std::ffi::IntoStringError),
#[error("Invalid serial mode")]
InvalidMode,
#[error("{0}")]
Rustmex(#[from] rustmex::Error),
}
impl Error {
fn id(&self) -> &str {
match self {
Error::MissingSerialMode => "serialbridge:missing_input",
Error::MissingPortName => "serialbridge:missing_input",
Error::MissingBaudrate => "serialbridge:missing_input",
Error::String(_) => "serialbridge:invalid_input",
Error::InvalidMode => "serialbridge:invalid_input",
Error::Rustmex(err) => err.id(),
}
}
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()
}
}
//! WARNING: panic is used as stated in the example at
//! [rustmex](https://gitlab.com/nielstermeer/rustmex/-/blob/master/examples/catch_panic/src/lib.rs?ref_type=heads).
mod error;
mod types;
use rustmex::{char::CharArray, prelude::*, MatlabClass};
use error::{Error, MapMexError};
#[rustmex::entrypoint]
fn serialbridge(lhs: Lhs, rhs: Rhs) -> rustmex::Result<()> {
let arg0 = rhs.first().mexerr(Error::MissingSerialMode)?;
// Get the mode argument ("Open", "Close", "Read", "Write")
let mode = get_mode(arg0);
let arg1 = rhs.get(1).error_if_missing(
"serialbridge:missing_input",
"Missing serial mode (second argument)",
)?;
Ok(())
}
fn get_mode(arg: &mxArray) -> Result<types::Mode, Error> {
CharArray::from_mx_array(arg)?
.get_cstring()
.into_string()?
.parse()
}
fn main() {
println!("Hello, world!");
}
use std::{
ffi::{CStr, CString},
ops::Deref,
str::FromStr,
};
use cstr::cstr;
use rustmex::{
convert::ToMatlab,
error,
numeric::{Numeric, NumericArray},
structs::{ScalarStruct, Struct},
MatlabClass, MxArray,
};
use crate::error::Error;
#[derive(Debug, Clone)]
pub struct Serial(ScalarStruct<MxArray>);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Open,
Close,
Read,
Write,
}
impl FromStr for Mode {
type Err = crate::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Open" => Ok(Mode::Open),
"Close" => Ok(Mode::Close),
"Read" => Ok(Mode::Read),
"Write" => Ok(Mode::Write),
_ => Err(Error::InvalidMode),
}
}
}
// #[derive(Debug, Clone)]
// struct ByteString(MxArray);
// impl From<&str> for ByteString {
// fn from(value: &str) -> Self {
// let raw = value.as_bytes();
// Self(
// Numeric::new(raw.into(), &[1, raw.len()])
// .expect("Failed to create byte string")
// .into_inner(),
// )
// }
// }
// impl ByteString {
// fn from_string(value: String) -> Self {
// value.as_str().into()
// }
// fn into_string(self) -> rustmex::Result<String> {
// let value = Numeric::<u8, MxArray>::from_mx_array(self.0)?.data();
// Ok(String::from_utf8(value.to_vec()).expect("Failed to convert byte string to string"))
// }
// }
// impl Deref for ByteString {
// type Target = MxArray;
// fn deref(&self) -> &Self::Target {
// &self.0
// }
// }
// impl Serial {
// pub fn new(device: String, baudrate: u32) -> Self {
// let device_f = cstr!("serialport");
// let baud_f = cstr!("baudrate");
// let mut s = Struct::new(&[1, 1], &[device_f, baud_f])
// .into_scalar()
// .unwrap();
// // let device = CString::new(device.into()).unwrap();
// s.set(device_f, *ByteString::from_string(device)).unwrap();
// s.set(baud_f, baudrate.to_matlab()).unwrap();
// Serial(s)
// }
// pub fn into_struct(self) -> ScalarStruct<MxArray> {
// self.0
// }
// pub fn from_struct(s: ScalarStruct<MxArray>) -> Self {
// Serial(s)
// }
// pub fn device(&self) -> rustmex::Result<String> {
// let device_f = cstr!("serialport");
// let a = self
// .0
// .get(device_f)
// .map(|x| x.ok_or_else(|| error!("serialbridge:missing_input", "Device not found")))?
// .map(|x| ByteString(x.to_owned()));
// }
// }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment