use crate::connection_config::*;
use crate::device::*;
use crate::ffi::connection_config::*;
use crate::ffi::connection_type::*;
use crate::ffi::helpers::*;
use std::mem;
use std::os::raw::c_char;
#[repr(C)]
pub struct DeviceC {
device_name: [c_char; CHAR_ARRAY_SIZE],
serial_number: [c_char; CHAR_ARRAY_SIZE],
connection_type: ConnectionType,
usb_connection_config: UsbConnectionConfigC,
serial_connection_config: SerialConnectionConfigC,
tcp_connection_config: TcpConnectionConfigC,
udp_connection_config: UdpConnectionConfigC,
bluetooth_connection_config: BluetoothConnectionConfigC,
file_connection_config: FileConnectionConfigC,
mux_connection_config: *mut MuxConnectionConfig,
}
impl Default for DeviceC {
fn default() -> Self {
Self {
device_name: EMPTY_CHAR_ARRAY,
serial_number: EMPTY_CHAR_ARRAY,
connection_type: ConnectionType::Usb,
usb_connection_config: Default::default(),
serial_connection_config: Default::default(),
tcp_connection_config: Default::default(),
udp_connection_config: Default::default(),
bluetooth_connection_config: Default::default(),
file_connection_config: Default::default(),
mux_connection_config: Default::default(),
}
}
}
impl From<&Device> for DeviceC {
fn from(device: &Device) -> Self {
let mut device_c: Self = Default::default();
device_c.device_name = str_to_char_array(&device.device_name);
device_c.serial_number = str_to_char_array(&device.serial_number);
match &device.connection_config {
ConnectionConfig::UsbConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Usb;
device_c.usb_connection_config = config.into();
}
ConnectionConfig::SerialConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Serial;
device_c.serial_connection_config = config.into();
}
ConnectionConfig::TcpConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Tcp;
device_c.tcp_connection_config = config.into();
}
ConnectionConfig::UdpConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Udp;
device_c.udp_connection_config = config.into();
}
ConnectionConfig::BluetoothConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Bluetooth;
device_c.bluetooth_connection_config = config.into();
}
ConnectionConfig::FileConnectionConfig(config) => {
device_c.connection_type = ConnectionType::File;
device_c.file_connection_config = config.into();
}
ConnectionConfig::MuxConnectionConfig(config) => {
device_c.connection_type = ConnectionType::Mux;
device_c.mux_connection_config = config.into();
}
}
device_c
}
}
impl From<DeviceC> for Device {
fn from(device: DeviceC) -> Self {
Self {
device_name: unsafe { char_array_to_string(&device.device_name) },
serial_number: unsafe { char_array_to_string(&device.serial_number) },
connection_config: match device.connection_type {
ConnectionType::Usb => ConnectionConfig::UsbConnectionConfig(device.usb_connection_config.into()),
ConnectionType::Serial => ConnectionConfig::SerialConnectionConfig(device.serial_connection_config.into()),
ConnectionType::Tcp => ConnectionConfig::TcpConnectionConfig(device.tcp_connection_config.into()),
ConnectionType::Udp => ConnectionConfig::UdpConnectionConfig(device.udp_connection_config.into()),
ConnectionType::Bluetooth => ConnectionConfig::BluetoothConnectionConfig(device.bluetooth_connection_config.into()),
ConnectionType::File => ConnectionConfig::FileConnectionConfig(device.file_connection_config.into()),
ConnectionType::Mux => ConnectionConfig::MuxConnectionConfig(device.mux_connection_config.into()),
},
}
}
}
#[no_mangle]
pub extern "C" fn XIMU3_device_free(device: DeviceC) {
if device.connection_type == ConnectionType::Mux {
XIMU3_mux_connection_config_free(device.mux_connection_config);
}
}
#[no_mangle]
pub extern "C" fn XIMU3_device_clone(mut device: DeviceC) -> DeviceC {
if device.connection_type == ConnectionType::Mux {
device.mux_connection_config = XIMU3_mux_connection_config_clone(device.mux_connection_config);
}
device
}
#[no_mangle]
pub extern "C" fn XIMU3_device_to_string(device: DeviceC) -> *const c_char {
str_to_char_ptr(&Device::from(device).to_string())
}
#[repr(C)]
pub struct Devices {
array: *mut DeviceC,
length: u32,
capacity: u32,
}
impl From<Vec<Device>> for Devices {
fn from(devices: Vec<Device>) -> Self {
let mut vector: Vec<DeviceC> = devices.iter().map(|device| device.into()).collect();
let devices = Self {
array: vector.as_mut_ptr(),
length: vector.len() as u32,
capacity: vector.capacity() as u32,
};
mem::forget(vector);
devices
}
}
#[no_mangle]
pub extern "C" fn XIMU3_devices_free(devices: Devices) {
if devices.array.is_null() {
return;
}
let vector = unsafe { Vec::from_raw_parts(devices.array, devices.length as usize, devices.capacity as usize) };
for device in vector {
XIMU3_device_free(device);
}
}