use std::marker::PhantomData;
#[cfg(has_subsystem_application)]
use libnvme_sys::nvme_subsystem_get_application;
#[cfg(has_subsystem_fw_rev)]
use libnvme_sys::nvme_subsystem_get_fw_rev;
#[cfg(has_subsystem_iopolicy)]
use libnvme_sys::nvme_subsystem_get_iopolicy;
#[cfg(has_subsystem_model)]
use libnvme_sys::nvme_subsystem_get_model;
#[cfg(has_subsystem_serial)]
use libnvme_sys::nvme_subsystem_get_serial;
use libnvme_sys::{
nvme_first_subsystem, nvme_host_t, nvme_next_subsystem, nvme_subsystem_get_name,
nvme_subsystem_get_nqn, nvme_subsystem_get_type, nvme_subsystem_t,
};
use crate::controller::Controllers;
use crate::util::cstr_to_str;
use crate::{Result, Root};
pub struct Subsystem<'r> {
inner: nvme_subsystem_t,
_marker: PhantomData<&'r Root>,
}
impl<'r> Subsystem<'r> {
pub(crate) fn from_raw(inner: nvme_subsystem_t) -> Self {
Subsystem {
inner,
_marker: PhantomData,
}
}
pub fn name(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_name(self.inner)) }
}
pub fn nqn(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_nqn(self.inner)) }
}
pub fn subsystem_type(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_type(self.inner)) }
}
#[cfg(has_subsystem_serial)]
pub fn serial(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_serial(self.inner)) }
}
#[cfg(has_subsystem_model)]
pub fn model(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_model(self.inner)) }
}
#[cfg(has_subsystem_fw_rev)]
pub fn firmware(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_fw_rev(self.inner)) }
}
#[cfg(has_subsystem_iopolicy)]
pub fn iopolicy(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_iopolicy(self.inner)) }
}
#[cfg(has_subsystem_application)]
pub fn application(&self) -> Result<&'r str> {
unsafe { cstr_to_str(nvme_subsystem_get_application(self.inner)) }
}
pub fn controllers(&self) -> Controllers<'r> {
Controllers::new(self.inner)
}
}
impl std::fmt::Debug for Subsystem<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Subsystem")
.field("name", &self.name().ok())
.field("nqn", &self.nqn().ok())
.finish()
}
}
pub struct Subsystems<'r> {
host: nvme_host_t,
cursor: nvme_subsystem_t,
_marker: PhantomData<&'r Root>,
}
impl<'r> Subsystems<'r> {
pub(crate) fn new(host: nvme_host_t) -> Self {
let cursor = unsafe { nvme_first_subsystem(host) };
Subsystems {
host,
cursor,
_marker: PhantomData,
}
}
}
impl<'r> Iterator for Subsystems<'r> {
type Item = Subsystem<'r>;
fn next(&mut self) -> Option<Self::Item> {
if self.cursor.is_null() {
return None;
}
let current = self.cursor;
self.cursor = unsafe { nvme_next_subsystem(self.host, current) };
Some(Subsystem::from_raw(current))
}
}