use crate::{try_gp_internal, Result, helper::{as_ref, chars_to_string}};
use std::fmt;
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PortType {
Serial,
Usb,
Disk,
PTPIp,
Ip,
UsbDiskDirect,
UsbScsi,
}
pub struct PortInfo {
pub(crate) inner: libgphoto2_sys::GPPortInfo,
}
pub(crate) struct PortInfoList {
pub(crate) inner: *mut libgphoto2_sys::GPPortInfoList,
}
impl Drop for PortInfoList {
fn drop(&mut self) {
unsafe {
libgphoto2_sys::gp_port_info_list_free(self.inner);
}
}
}
impl From<libgphoto2_sys::GPPortInfo> for PortInfo {
fn from(inner: libgphoto2_sys::GPPortInfo) -> Self {
Self { inner }
}
}
impl fmt::Debug for PortInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PortInfo")
.field("name", &self.name().ok())
.field("path", &self.path().ok())
.field("port_type", &self.port_type().ok().flatten())
.finish()
}
}
as_ref!(PortInfoList -> libgphoto2_sys::GPPortInfoList, *self.inner);
as_ref!(PortInfo -> libgphoto2_sys::GPPortInfo, self.inner);
impl PortType {
fn new(port_type: libgphoto2_sys::GPPortType) -> Option<Self> {
use libgphoto2_sys::GPPortType;
match port_type {
GPPortType::GP_PORT_NONE => None,
GPPortType::GP_PORT_SERIAL => Some(Self::Serial),
GPPortType::GP_PORT_USB => Some(Self::Usb),
GPPortType::GP_PORT_DISK => Some(Self::Disk),
GPPortType::GP_PORT_PTPIP => Some(Self::PTPIp),
GPPortType::GP_PORT_IP => Some(Self::Ip),
GPPortType::GP_PORT_USB_DISK_DIRECT => Some(Self::UsbDiskDirect),
GPPortType::GP_PORT_USB_SCSI => Some(Self::UsbScsi),
}
}
}
impl PortInfo {
pub fn name(&self) -> Result<String> {
try_gp_internal!(gp_port_info_get_name(self.inner, &out name));
Ok(chars_to_string(name))
}
pub fn path(&self) -> Result<String> {
try_gp_internal!(gp_port_info_get_path(self.inner, &out path));
Ok(chars_to_string(path))
}
pub fn port_type(&self) -> Result<Option<PortType>> {
try_gp_internal!(gp_port_info_get_type(self.inner, &out port_type));
Ok(PortType::new(port_type))
}
}
impl PortInfoList {
pub(crate) fn new() -> Result<Self> {
try_gp_internal!(gp_port_info_list_new(&out port_info_list));
try_gp_internal!(gp_port_info_list_load(port_info_list));
Ok(Self { inner: port_info_list })
}
pub(crate) fn get_port_info(&self, p: i32) -> Result<PortInfo> {
try_gp_internal!(gp_port_info_list_get_info(self.inner, p, &out port_info));
Ok(port_info.into())
}
}