rustmex_core 0.3.0

Rustmex libary with core functionality
Documentation
/*!
 * Distinghuising matlab types from eachother
 */
use crate::raw::{
	mxClassID_mxUNKNOWN_CLASS as UNKNOWN_CLASS,
	mxClassID_mxCELL_CLASS as CELL_CLASS,
	mxClassID_mxSTRUCT_CLASS as STRUCT_CLASS,
	mxClassID_mxCHAR_CLASS as CHAR_CLASS,
	mxClassID_mxVOID_CLASS as VOID_CLASS,
	mxClassID_mxFUNCTION_CLASS as FUNCTION_CLASS,

	mxClassID_mxDOUBLE_CLASS as DOUBLE_CLASS,
	mxClassID_mxSINGLE_CLASS as SINGLE_CLASS,

	mxClassID_mxLOGICAL_CLASS as LOGICAL_CLASS,
	mxClassID_mxINT8_CLASS as I8_CLASS,
	mxClassID_mxUINT8_CLASS as U8_CLASS,
	mxClassID_mxINT16_CLASS as I16_CLASS,
	mxClassID_mxUINT16_CLASS as U16_CLASS,
	mxClassID_mxINT32_CLASS as I32_CLASS,
	mxClassID_mxUINT32_CLASS as U32_CLASS,
	mxClassID_mxINT64_CLASS as I64_CLASS,
	mxClassID_mxUINT64_CLASS as U64_CLASS,
	mxClassID_mxOPAQUE_CLASS as OPAQUE_CLASS,
	mxClassID_mxOBJECT_CLASS as OBJECT_CLASS,

	mxClassID,
};

#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
#[repr(u32)]
pub enum ClassID {
	Unknown = UNKNOWN_CLASS,
	Cell = CELL_CLASS,
	Struct = STRUCT_CLASS,
	Char = CHAR_CLASS,
	Void = VOID_CLASS,

	Logical = LOGICAL_CLASS,

	Double = DOUBLE_CLASS,
	Single = SINGLE_CLASS,

	I8 = I8_CLASS,
	U8 = U8_CLASS,

	I16 = I16_CLASS,
	U16 = U16_CLASS,

	I32 = I32_CLASS,
	U32 = U32_CLASS,

	I64 = I64_CLASS,
	U64 = U64_CLASS,

	Function = FUNCTION_CLASS,

	/// Opaque classes are discriminants only documented for the matlab backends;
	/// GNU/Octave will not return this values.
	//#[cfg(any(not(feature = "octave"), feature = "doc"))]
	Opaque = OPAQUE_CLASS,
	/// Object classes are discriminants only documented for the matlab backends;
	/// GNU/Octave will not return this values.
	//#[cfg(any(not(feature = "octave"), feature = "doc"))]
	Object = OBJECT_CLASS,
}

/**
 * Convert an [`mxClassID`] into a [`ClassID`] enum. This conversion was assumed to be
 * infallible, but isn't because Matlab (but not Octave as far as I can see) use the
 * higher discriminants as ClassID's for user defined classes.
 */
impl TryFrom<mxClassID> for ClassID {
	type Error = mxClassID;
	fn try_from(cid: mxClassID) -> Result<Self, Self::Error> {
		Ok(match cid {
			UNKNOWN_CLASS => Self::Unknown,
			CELL_CLASS => Self::Cell,
			STRUCT_CLASS => Self::Struct,
			LOGICAL_CLASS => Self::Logical,
			CHAR_CLASS => Self::Char,
			VOID_CLASS => Self::Void,

			DOUBLE_CLASS => Self::Double,
			SINGLE_CLASS => Self::Single,

			I8_CLASS => Self::I8,
			U8_CLASS => Self::U8,
			U16_CLASS => Self::U16,
			I16_CLASS => Self::I16,
			U32_CLASS => Self::U32,
			I32_CLASS => Self::I32,
			U64_CLASS => Self::U64,
			I64_CLASS => Self::I64,

			FUNCTION_CLASS => Self::Function,

			OBJECT_CLASS => Self::Object,
			OPAQUE_CLASS => Self::Opaque,

			_ => return Err(cid)
		})
	}
}

impl From<ClassID> for mxClassID {
	fn from(cid: ClassID) -> Self {
		// Since the ClassID can only contain valid Class ID's, it can be safely
		// cast to the underlying value.
		cid as Self
	}
}

impl PartialEq<mxClassID> for ClassID {
	fn eq(&self, rhs: &mxClassID) -> bool {
		*self as mxClassID == *rhs
	}
}

impl PartialEq<ClassID> for mxClassID {
	fn eq(&self, rhs: &ClassID) -> bool {
		// this invokes PartialEq<mxClassID>::eq for ClassID
		rhs == self
	}
}