use crate::error::GCPluginABIError;
use crate::{GCAbiConversion, copy_str_to_c};
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::ffi::CStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum StopBits {
One,
Two,
}
impl StopBits {
pub fn from_c(c_stop_bits: gc_abi_sys::GCStopBits) -> Result<Self, GCPluginABIError> {
match c_stop_bits {
gc_abi_sys::GCStopBits_GC_STOP_BITS_ONE => Ok(StopBits::One),
gc_abi_sys::GCStopBits_GC_STOP_BITS_TWO => Ok(StopBits::Two),
_ => Err(GCPluginABIError::ErrorInvalidCEnum(format!(
"Invalid stop bits value from C ABI: {}",
c_stop_bits
))),
}
}
pub fn to_c(&self) -> gc_abi_sys::GCStopBits {
match self {
StopBits::One => gc_abi_sys::GCStopBits_GC_STOP_BITS_ONE,
StopBits::Two => gc_abi_sys::GCStopBits_GC_STOP_BITS_TWO,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Parity {
None,
Odd,
Even,
}
impl Parity {
pub fn from_c(c_parity: gc_abi_sys::GCParity) -> Result<Self, GCPluginABIError> {
match c_parity {
gc_abi_sys::GCParity_GC_PARITY_NONE => Ok(Parity::None),
gc_abi_sys::GCParity_GC_PARITY_ODD => Ok(Parity::Odd),
gc_abi_sys::GCParity_GC_PARITY_EVEN => Ok(Parity::Even),
_ => Err(GCPluginABIError::ErrorInvalidCEnum(format!(
"Invalid parity value from C ABI: {}",
c_parity
))),
}
}
pub fn to_c(&self) -> gc_abi_sys::GCParity {
match self {
Parity::None => gc_abi_sys::GCParity_GC_PARITY_NONE,
Parity::Odd => gc_abi_sys::GCParity_GC_PARITY_ODD,
Parity::Even => gc_abi_sys::GCParity_GC_PARITY_EVEN,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum DataBits {
Five,
Six,
Seven,
Eight,
}
impl DataBits {
pub fn from_c(c_data_bits: gc_abi_sys::GCDataBits) -> Result<Self, GCPluginABIError> {
match c_data_bits {
gc_abi_sys::GCDataBits_GC_DATA_BITS_FIVE => Ok(DataBits::Five),
gc_abi_sys::GCDataBits_GC_DATA_BITS_SIX => Ok(DataBits::Six),
gc_abi_sys::GCDataBits_GC_DATA_BITS_SEVEN => Ok(DataBits::Seven),
gc_abi_sys::GCDataBits_GC_DATA_BITS_EIGHT => Ok(DataBits::Eight),
_ => Err(GCPluginABIError::ErrorInvalidCEnum(format!(
"Invalid data bits value from C ABI: {}",
c_data_bits
))),
}
}
pub fn to_c(&self) -> gc_abi_sys::GCDataBits {
match self {
DataBits::Five => gc_abi_sys::GCDataBits_GC_DATA_BITS_FIVE,
DataBits::Six => gc_abi_sys::GCDataBits_GC_DATA_BITS_SIX,
DataBits::Seven => gc_abi_sys::GCDataBits_GC_DATA_BITS_SEVEN,
DataBits::Eight => gc_abi_sys::GCDataBits_GC_DATA_BITS_EIGHT,
}
}
}
#[repr(transparent)]
#[derive(Debug)]
pub struct GCEthernetInterface(gc_abi_sys::sGCEthernetInterface);
impl GCEthernetInterface {
#[doc(hidden)]
pub fn new(interface: &str) -> Result<Self, GCPluginABIError> {
let interface_buf = copy_str_to_c(interface)?;
Ok(GCEthernetInterface(gc_abi_sys::sGCEthernetInterface { interface: interface_buf }))
}
pub fn interface(&self) -> Cow<'_, str> {
unsafe { CStr::from_ptr(self.0.interface.as_ptr()).to_string_lossy() }
}
}
unsafe impl GCAbiConversion for GCEthernetInterface {
type CType = gc_abi_sys::sGCEthernetInterface;
fn from_c(c_type: Self::CType) -> Self {
GCEthernetInterface(c_type)
}
fn into_c(self) -> Self::CType {
self.0
}
}
#[repr(transparent)]
#[derive(Debug)]
pub struct GCSerialInterface(gc_abi_sys::sGCSerialInterface);
impl GCSerialInterface {
#[doc(hidden)]
pub fn new(interface: &str, baud_rate: u32, parity: Parity, stop_bits: StopBits, data_bits: DataBits) -> Result<Self, GCPluginABIError> {
let interface_buf = copy_str_to_c(interface)?;
Ok(GCSerialInterface(gc_abi_sys::sGCSerialInterface {
interface: interface_buf,
baud_rate,
parity: parity.to_c(),
stop_bits: stop_bits.to_c(),
data_bits: data_bits.to_c(),
}))
}
pub fn interface<'a>(&'a self) -> Cow<'a, str> {
unsafe { CStr::from_ptr(self.0.interface.as_ptr()).to_string_lossy() }
}
pub fn baud_rate(&self) -> u32 {
self.0.baud_rate
}
pub fn parity(&self) -> Result<Parity, GCPluginABIError> {
Parity::from_c(self.0.parity)
}
pub fn stop_bits(&self) -> Result<StopBits, GCPluginABIError> {
StopBits::from_c(self.0.stop_bits)
}
pub fn data_bits(&self) -> Result<DataBits, GCPluginABIError> {
DataBits::from_c(self.0.data_bits)
}
}
unsafe impl GCAbiConversion for GCSerialInterface {
type CType = gc_abi_sys::sGCSerialInterface;
fn from_c(c_type: Self::CType) -> Self {
GCSerialInterface(c_type)
}
fn into_c(self) -> Self::CType {
self.0
}
}