use crate::hardware_id::HardwareIdRef;
use crate::hardware_id::Manufacturer as HardwareIdManufacturer;
use crate::hardware_id::Model as HardwareIdModel;
use crate::hardware_id::PartNumber as HardwareIdPartNumber;
use crate::hardware_id::SerialNumber as HardwareIdSerialNumber;
use crate::schema::pcie_device::PcieDevice as PcieDeviceSchema;
use crate::schema::pcie_device_collection::PcieDeviceCollection as PcieDeviceCollectionSchema;
use crate::Error;
use crate::NvBmc;
use crate::Resource;
use crate::ResourceProvidesStatus;
use crate::ResourceSchema;
use crate::ResourceStatusSchema;
use nv_redfish_core::Bmc;
use nv_redfish_core::NavProperty;
use std::marker::PhantomData;
use std::sync::Arc;
use tagged_types::TaggedType;
pub struct PcieDeviceCollection<B: Bmc> {
bmc: NvBmc<B>,
collection: Arc<PcieDeviceCollectionSchema>,
}
impl<B: Bmc> PcieDeviceCollection<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
nav: &NavProperty<PcieDeviceCollectionSchema>,
) -> Result<Self, Error<B>> {
let collection = bmc.expand_property(nav).await?;
Ok(Self {
bmc: bmc.clone(),
collection,
})
}
pub async fn members(&self) -> Result<Vec<PcieDevice<B>>, Error<B>> {
let mut members = Vec::new();
for m in &self.collection.members {
members.push(PcieDevice::new(&self.bmc, m).await?);
}
Ok(members)
}
}
#[doc(hidden)]
pub enum PcieDeviceTag {}
pub type Manufacturer<T> = HardwareIdManufacturer<T, PcieDeviceTag>;
pub type Model<T> = HardwareIdModel<T, PcieDeviceTag>;
pub type PartNumber<T> = HardwareIdPartNumber<T, PcieDeviceTag>;
pub type SerialNumber<T> = HardwareIdSerialNumber<T, PcieDeviceTag>;
pub type FirmwareVersion<T> = TaggedType<T, FirmwareVersionTag>;
#[doc(hidden)]
#[derive(tagged_types::Tag)]
#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[transparent(Debug, Display, Serialize, Deserialize)]
#[capability(inner_access, cloned)]
pub enum FirmwareVersionTag {}
pub struct PcieDevice<B: Bmc> {
data: Arc<PcieDeviceSchema>,
_marker: PhantomData<B>,
}
impl<B: Bmc> PcieDevice<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
nav: &NavProperty<PcieDeviceSchema>,
) -> Result<Self, Error<B>> {
nav.get(bmc.as_ref())
.await
.map_err(crate::Error::Bmc)
.map(|data| Self {
data,
_marker: PhantomData,
})
}
#[must_use]
pub fn raw(&self) -> Arc<PcieDeviceSchema> {
self.data.clone()
}
#[must_use]
pub fn hardware_id(&self) -> HardwareIdRef<'_, PcieDeviceTag> {
HardwareIdRef {
manufacturer: self
.data
.manufacturer
.as_ref()
.and_then(Option::as_deref)
.map(Manufacturer::new),
model: self
.data
.model
.as_ref()
.and_then(Option::as_deref)
.map(Model::new),
part_number: self
.data
.part_number
.as_ref()
.and_then(Option::as_deref)
.map(PartNumber::new),
serial_number: self
.data
.serial_number
.as_ref()
.and_then(Option::as_deref)
.map(SerialNumber::new),
}
}
#[must_use]
pub fn firmware_version(&self) -> Option<FirmwareVersion<&str>> {
self.data
.firmware_version
.as_ref()
.and_then(Option::as_ref)
.map(String::as_str)
.map(FirmwareVersion::new)
}
}
impl<B: Bmc> Resource for PcieDevice<B> {
fn resource_ref(&self) -> &ResourceSchema {
&self.data.as_ref().base
}
}
impl<B: Bmc> ResourceProvidesStatus for PcieDevice<B> {
fn resource_status_ref(&self) -> Option<&ResourceStatusSchema> {
self.data.status.as_ref()
}
}