use std::fmt;
use std::fs::File;
use std::os::unix::prelude::*;
use std::path::Path;
use crate::{RawInfo, Result};
pub struct Device(OwnedFd);
impl Device {
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
let file = File::options()
.read(true)
.write(true)
.custom_flags(libc::O_NONBLOCK)
.open(path)?;
Ok(Self(file.into()))
}
}
impl AsFd for Device {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl From<Device> for OwnedFd {
#[inline]
fn from(device: Device) -> Self {
device.0
}
}
impl From<OwnedFd> for Device {
#[inline]
fn from(owned_fd: OwnedFd) -> Self {
Self(owned_fd)
}
}
impl FromRawFd for Device {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
Self(FromRawFd::from_raw_fd(fd))
}
}
impl IntoRawFd for Device {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
impl fmt::Debug for Device {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn get_raw_info(this: &Device) -> Result<RawInfo> {
this.__get_raw_info()
}
fn get_raw_name(this: &Device) -> Result<String> {
this.__get_raw_name()
}
let fd = self.as_raw_fd();
let mut b = f.debug_struct("Device");
b.field("fd", &fd);
if let Ok(raw_name) = get_raw_name(self) {
b.field("name", &raw_name);
}
if let Ok(raw_info) = get_raw_info(self) {
b.field("bus", &raw_info.bus_type()).field(
"id",
&format_args!("{:04x}:{:04x}", raw_info.vendor(), raw_info.product()),
);
}
b.finish()
}
}