mod status;
#[cfg(unix)]
mod unix_trait_impls;
#[cfg(windows)]
mod windows_trait_impls;
pub use self::status::DriveStatus;
use crate::{error::Result, platform::device::DeviceHandle};
use std::{path::Path, time::Instant};
pub struct Device {
handle: DeviceHandle,
}
impl Device {
pub fn open(path: impl AsRef<Path>) -> Result<Self> {
Ok(Self {
handle: DeviceHandle::open(path)?,
})
}
pub fn eject(&self) -> Result<()> {
self.handle.eject()
}
pub fn retract(&self) -> Result<()> {
self.handle.retract()
}
pub fn toggle_eject(&self) -> Result<bool> {
if let Ok(status) = self.status() {
if status.tray_open() {
self.retract()?;
Ok(false)
} else {
self.eject()?;
Ok(true)
}
} else {
let time = Instant::now();
self.eject()?;
if time.elapsed().as_millis() < 100 {
self.retract()?;
Ok(false)
} else {
Ok(true)
}
}
}
pub fn lock_ejection(&self) -> Result<EjectionLock> {
self.handle.set_ejection_lock(true)?;
Ok(EjectionLock { device: self })
}
pub fn status(&self) -> Result<DriveStatus> {
self.handle.status()
}
}
pub struct EjectionLock<'a> {
device: &'a Device,
}
impl Drop for EjectionLock<'_> {
fn drop(&mut self) {
let _ = self.device.handle.set_ejection_lock(false);
}
}