use crate::helper::{as_ref, bitflags, char_slice_to_cow};
use crate::task::BackgroundPtr;
use crate::{context::Context, try_gp_internal, Result};
use std::{borrow::Cow, fmt};
pub(crate) struct AbilitiesList {
pub(crate) inner: BackgroundPtr<libgphoto2_sys::CameraAbilitiesList>,
}
pub struct Abilities {
pub(crate) inner: Box<libgphoto2_sys::CameraAbilities>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UsbInfo {
pub vendor: u16,
pub product: u16,
pub class: u8,
pub subclass: u8,
pub protocol: u8,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub enum CameraDriverStatus {
Production,
Testing,
Experimental,
Deprecated,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub enum DeviceType {
Camera,
AudioPlayer,
}
impl Drop for AbilitiesList {
fn drop(&mut self) {
try_gp_internal!(gp_abilities_list_free(*self.inner).unwrap());
}
}
impl From<libgphoto2_sys::GphotoDeviceType> for DeviceType {
fn from(device_type: libgphoto2_sys::GphotoDeviceType) -> Self {
use libgphoto2_sys::GphotoDeviceType;
match device_type {
GphotoDeviceType::GP_DEVICE_STILL_CAMERA => Self::Camera,
GphotoDeviceType::GP_DEVICE_AUDIO_PLAYER => Self::AudioPlayer,
}
}
}
impl From<libgphoto2_sys::CameraDriverStatus> for CameraDriverStatus {
fn from(status: libgphoto2_sys::CameraDriverStatus) -> Self {
use libgphoto2_sys::CameraDriverStatus as GPDriverStatus;
match status {
GPDriverStatus::GP_DRIVER_STATUS_PRODUCTION => Self::Production,
GPDriverStatus::GP_DRIVER_STATUS_TESTING => Self::Testing,
GPDriverStatus::GP_DRIVER_STATUS_EXPERIMENTAL => Self::Experimental,
GPDriverStatus::GP_DRIVER_STATUS_DEPRECATED => Self::Deprecated,
}
}
}
impl fmt::Debug for Abilities {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Abilities")
.field("id", &self.id())
.field("model", &self.model())
.field("driver_status", &self.driver_status())
.field("camera_operations", &self.camera_operations())
.field("file_operations", &self.file_operations())
.field("folder_operations", &self.folder_operations())
.field("device_type", &self.device_type())
.field("usb_info", &self.usb_info())
.finish()
}
}
as_ref!(AbilitiesList -> libgphoto2_sys::CameraAbilitiesList, **self.inner);
as_ref!(Abilities -> libgphoto2_sys::CameraAbilities, self.inner);
impl AbilitiesList {
pub(crate) fn new_inner(context: &Context) -> Result<Self> {
try_gp_internal!(gp_abilities_list_new(&out abilities_inner)?);
try_gp_internal!(gp_abilities_list_load(abilities_inner, *context.inner)?);
Ok(Self { inner: BackgroundPtr(abilities_inner) })
}
}
impl Abilities {
pub fn id(&self) -> Cow<str> {
char_slice_to_cow(&self.inner.id)
}
pub fn model(&self) -> Cow<str> {
char_slice_to_cow(&self.inner.model)
}
pub fn driver_status(&self) -> CameraDriverStatus {
self.inner.status.into()
}
pub fn camera_operations(&self) -> CameraOperations {
self.inner.operations.into()
}
pub fn file_operations(&self) -> FileOperations {
self.inner.file_operations.into()
}
pub fn folder_operations(&self) -> FolderOperations {
self.inner.folder_operations.into()
}
pub fn device_type(&self) -> DeviceType {
self.inner.device_type.into()
}
pub fn usb_info(&self) -> UsbInfo {
#[allow(clippy::as_conversions)]
UsbInfo {
vendor: self.inner.usb_vendor as u16,
product: self.inner.usb_product as u16,
class: self.inner.usb_class as u8,
subclass: self.inner.usb_subclass as u8,
protocol: self.inner.usb_protocol as u8,
}
}
}
bitflags!(
CameraOperations = CameraOperation {
capture_image: GP_OPERATION_CAPTURE_IMAGE,
capture_video: GP_OPERATION_CAPTURE_VIDEO,
capture_audio: GP_OPERATION_CAPTURE_AUDIO,
capture_preview: GP_OPERATION_CAPTURE_PREVIEW,
configure: GP_OPERATION_CONFIG,
trigger_capture: GP_OPERATION_TRIGGER_CAPTURE,
}
);
bitflags!(
FileOperations = CameraFileOperation {
delete: GP_FILE_OPERATION_DELETE,
preview: GP_FILE_OPERATION_PREVIEW,
raw: GP_FILE_OPERATION_RAW,
audio: GP_FILE_OPERATION_AUDIO,
exif: GP_FILE_OPERATION_EXIF,
}
);
bitflags!(
FolderOperations = CameraFolderOperation {
delete_all: GP_FOLDER_OPERATION_DELETE_ALL,
put_file: GP_FOLDER_OPERATION_PUT_FILE,
make_dir: GP_FOLDER_OPERATION_MAKE_DIR,
remove_dir: GP_FOLDER_OPERATION_REMOVE_DIR,
}
);