Skip to content

Commit

Permalink
Create Type Support for Enums
Browse files Browse the repository at this point in the history
Added typing of API for enum values and tested
  • Loading branch information
JamesMc86 committed Mar 23, 2022
1 parent b75dde2 commit 03cd15a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 4 deletions.
4 changes: 3 additions & 1 deletion ni-syscfg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ edition = "2021"

[dependencies]
ni-syscfg-sys = { path = "../ni-syscfg-sys" }
thiserror = "1"
thiserror = "1"
num-derive = "0.3"
num-traits = "0.2"
58 changes: 58 additions & 0 deletions ni-syscfg/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub enum NiSystemConfigurationError {
IntoStringError(#[from] std::ffi::IntoStringError),
#[error("Null in String from API")]
NulStringError(#[from] std::ffi::NulError),
#[error("Unexpected Enum Value from API: {0}")]
UnexpectedEnumValue(i32),
}

#[derive(Clone, Copy, Debug)]
Expand All @@ -20,6 +22,34 @@ pub enum NiSysCfgApiStatus {
FoundCachedOfflineSystem,
RestartLocalhostInitiated,
ChangedPropertyNotSaved,
NotImplemented,
NullPointer,
Fail,
Unexpected,
OutOfMemory,
InvalidArg,
OperationTimedOut,
FileNotFound,
InvalidMACFormat,
PropMismatch,
PropDoesNotExist,
UriIllegalSyntax,
UriTargetDoesNotExist,
UriExpertDoesNotExist,
ItemDoesNotExist,
InvalidMode,
SysConfigApiNotInstalled,
NameSyntaxIllegal,
NameCollision,
NoPropValidated,
UriUnauthorized,
RenameResourceDependencies,
ValueInvalid,
ValuesInconsistent,
Canceled,
ResponseSyntax,
ResourceIsNotPresent,
ResourceIsSimulated,
}

impl From<i32> for NiSysCfgApiStatus {
Expand All @@ -32,6 +62,34 @@ impl From<i32> for NiSysCfgApiStatus {
NISysCfgStatus_NISysCfg_FoundCachedOfflineSystem => Self::FoundCachedOfflineSystem,
NISysCfgStatus_NISysCfg_RestartLocalhostInitiated => Self::RestartLocalhostInitiated,
NISysCfgStatus_NISysCfg_ChangedPropertyNotSaved => Self::ChangedPropertyNotSaved,
NISysCfgStatus_NISysCfg_NotImplemented => Self::NotImplemented,
NISysCfgStatus_NISysCfg_NullPointer => Self::NullPointer,
NISysCfgStatus_NISysCfg_Fail => Self::Fail,
NISysCfgStatus_NISysCfg_Unexpected => Self::Unexpected,
NISysCfgStatus_NISysCfg_OutOfMemory => Self::OutOfMemory,
NISysCfgStatus_NISysCfg_InvalidArg => Self::InvalidArg,
NISysCfgStatus_NISysCfg_OperationTimedOut => Self::OperationTimedOut,
NISysCfgStatus_NISysCfg_FileNotFound => Self::FileNotFound,
NISysCfgStatus_NISysCfg_InvalidMACFormat => Self::InvalidMACFormat,
NISysCfgStatus_NISysCfg_PropMismatch => Self::PropMismatch,
NISysCfgStatus_NISysCfg_PropDoesNotExist => Self::PropDoesNotExist,
NISysCfgStatus_NISysCfg_UriIllegalSyntax => Self::UriIllegalSyntax,
NISysCfgStatus_NISysCfg_UriTargetDoesNotExist => Self::UriTargetDoesNotExist,
NISysCfgStatus_NISysCfg_UriExpertDoesNotExist => Self::UriExpertDoesNotExist,
NISysCfgStatus_NISysCfg_ItemDoesNotExist => Self::ItemDoesNotExist,
NISysCfgStatus_NISysCfg_InvalidMode => Self::InvalidMode,
NISysCfgStatus_NISysCfg_SysConfigAPINotInstalled => Self::SysConfigApiNotInstalled,
NISysCfgStatus_NISysCfg_NameSyntaxIllegal => Self::NameSyntaxIllegal,
NISysCfgStatus_NISysCfg_NameCollision => Self::NameCollision,
NISysCfgStatus_NISysCfg_NoPropValidated => Self::NoPropValidated,
NISysCfgStatus_NISysCfg_UriUnauthorized => Self::UriUnauthorized,
NISysCfgStatus_NISysCfg_RenameResourceDependencies => Self::RenameResourceDependencies,
NISysCfgStatus_NISysCfg_ValueInvalid => Self::ValueInvalid,
NISysCfgStatus_NISysCfg_ValuesInconsistent => Self::ValuesInconsistent,
NISysCfgStatus_NISysCfg_Canceled => Self::Canceled,
NISysCfgStatus_NISysCfg_ResponseSyntax => Self::ResponseSyntax,
NISysCfgStatus_NISysCfg_ResourceIsNotPresent => Self::ResourceIsNotPresent,
NISysCfgStatus_NISysCfg_ResourceIsSimulated => Self::ResourceIsSimulated,
_ => Self::Unknown(item),
}
}
Expand Down
76 changes: 75 additions & 1 deletion ni-syscfg/src/parameters.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::error::{api_status, Result};
use crate::error::{api_status, NiSystemConfigurationError, Result};
/// Put a parameter interface type for all supported types here.
/// this can be thought of as a middleware. Handling type conversions but only loosly wrapping the ffi.
///
Expand All @@ -9,6 +9,8 @@ use crate::error::{api_status, Result};
/// also combine strings into here.
///
use ni_syscfg_sys::*;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::ffi::{c_void, CString};

pub fn new_simple_string() -> CString {
Expand Down Expand Up @@ -101,3 +103,75 @@ impl ReadableParameter for String {
Ok(value.into_string()?)
}
}

/// Marker trait for enums to be used as property values.
trait ValueEnum: FromPrimitive {}

impl<T> ReadableParameter for T
where
T: ValueEnum,
{
fn read_resource_parameter(
handle: NISysCfgResourceHandle,
id: NISysCfgResourceProperty,
) -> Result<T> {
let mut value = 0i32;
let status = unsafe {
api_status(NISysCfgGetResourceProperty(
handle,
id,
&mut value as *mut _ as *mut c_void,
))?
};
if let Some(inner) = T::from_i32(value) {
Ok(inner)
} else {
Err(NiSystemConfigurationError::UnexpectedEnumValue(value))
}
}

fn read_resource_indexed_parameter(
handle: NISysCfgResourceHandle,
id: NISysCfgIndexedProperty,
index: u32,
) -> Result<T> {
let mut value = 0i32;
let status = unsafe {
api_status(NISysCfgGetResourceIndexedProperty(
handle,
id,
index,
&mut value as *mut _ as *mut c_void,
))?
};
if let Some(inner) = T::from_i32(value) {
Ok(inner)
} else {
Err(NiSystemConfigurationError::UnexpectedEnumValue(value))
}
}
}

#[repr(i32)]
#[derive(FromPrimitive, Copy, Clone, Debug)]
pub enum BusType {
BuiltIn = NISysCfgBusType_NISysCfgBusTypeBuiltIn,
PciPxi = NISysCfgBusType_NISysCfgBusTypePciPxi,
Usb = NISysCfgBusType_NISysCfgBusTypeUsb,
Gpib = NISysCfgBusType_NISysCfgBusTypeGpib,
Vxi = NISysCfgBusType_NISysCfgBusTypeVxi,
Serial = NISysCfgBusType_NISysCfgBusTypeSerial,
TcpIp = NISysCfgBusType_NISysCfgBusTypeTcpIp,
CompactRio = NISysCfgBusType_NISysCfgBusTypeCompactRio,
Scxi = NISysCfgBusType_NISysCfgBusTypeScxi,
CompactDaq = NISysCfgBusType_NISysCfgBusTypeCompactDaq,
SwitchBlock = NISysCfgBusType_NISysCfgBusTypeSwitchBlock,
Scc = NISysCfgBusType_NISysCfgBusTypeScc,
FireWire = NISysCfgBusType_NISysCfgBusTypeFireWire,
Accessory = NISysCfgBusType_NISysCfgBusTypeAccessory,
Can = NISysCfgBusType_NISysCfgBusTypeCan,
SwitchBlockDevice = NISysCfgBusType_NISysCfgBusTypeSwitchBlockDevice,
Slsc = 16,
}

impl ValueEnum for BusType {}
10 changes: 9 additions & 1 deletion ni-syscfg/src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::marker::PhantomData;

use crate::error::{api_status, NiSysCfgApiStatus, Result};
use crate::handles::close_handle;
use crate::parameters::ReadableParameter;
use crate::parameters::{BusType, ReadableParameter};
use crate::session::Session;
use ni_syscfg_sys::*;

Expand Down Expand Up @@ -73,6 +73,14 @@ impl Resource {
) -> Result<T> {
T::read_resource_parameter(self.handle, parameter.id)
}

//Specific parameters follow.
pub fn connects_to_bus_type(&self) -> Result<BusType> {
BusType::read_resource_parameter(
self.handle,
NISysCfgResourceProperty_NISysCfgResourcePropertyConnectsToBusType,
)
}
}

impl Drop for Resource {
Expand Down
5 changes: 4 additions & 1 deletion ni-syscfg/tests/list_hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ fn test_list_hardware() {

for hardware in session.find_hardware().expect("Couldn't List Hardware") {
let name = hardware.get_name().expect("Couldn't Get hardware Name");
println!("Hardware found {name}");
let bus_type = hardware
.connects_to_bus_type()
.expect("Couldnt get bus type");
println!("Hardware found {name} connected to {bus_type:?}");
}
}

0 comments on commit 03cd15a

Please sign in to comment.