use crate::patch_support::CollectionWithPatch;
use crate::patch_support::Payload;
use crate::patch_support::ReadPatchFn;
use crate::schema::resource::ResourceCollection;
use crate::schema::software_inventory::SoftwareInventory as SoftwareInventorySchema;
use crate::schema::software_inventory_collection::SoftwareInventoryCollection as SoftwareInventoryCollectionSchema;
use crate::Error;
use crate::NvBmc;
use crate::Resource;
use crate::ResourceSchema;
use nv_redfish_core::Bmc;
use nv_redfish_core::EdmDateTimeOffset;
use nv_redfish_core::NavProperty;
use std::convert::identity;
use std::sync::Arc;
use tagged_types::TaggedType;
pub type Version = TaggedType<String, VersionTag>;
pub type VersionRef<'a> = TaggedType<&'a str, VersionTag>;
#[doc(hidden)]
#[derive(tagged_types::Tag)]
#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
#[capability(inner_access, cloned)]
pub enum VersionTag {}
pub type ReleaseDate = TaggedType<EdmDateTimeOffset, ReleaseDateTag>;
#[doc(hidden)]
#[derive(tagged_types::Tag)]
#[implement(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
#[capability(inner_access, cloned)]
pub enum ReleaseDateTag {}
pub struct SoftwareInventory<B: Bmc> {
#[allow(dead_code)]
bmc: NvBmc<B>,
data: Arc<SoftwareInventorySchema>,
}
impl<B: Bmc> SoftwareInventory<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
nav: &NavProperty<SoftwareInventorySchema>,
read_patch_fn: Option<&ReadPatchFn>,
) -> Result<Self, Error<B>> {
if let Some(read_patch_fn) = read_patch_fn {
Payload::get(bmc.as_ref(), nav, read_patch_fn.as_ref()).await
} else {
nav.get(bmc.as_ref()).await.map_err(Error::Bmc)
}
.map(|data| Self {
bmc: bmc.clone(),
data,
})
}
#[must_use]
pub fn raw(&self) -> Arc<SoftwareInventorySchema> {
self.data.clone()
}
#[must_use]
pub fn version(&self) -> Option<VersionRef<'_>> {
self.data
.version
.as_ref()
.and_then(Option::as_deref)
.map(VersionRef::new)
}
#[must_use]
pub fn release_date(&self) -> Option<ReleaseDate> {
self.data
.release_date
.and_then(identity)
.map(ReleaseDate::new)
}
}
impl<B: Bmc> Resource for SoftwareInventory<B> {
fn resource_ref(&self) -> &ResourceSchema {
&self.data.as_ref().base
}
}
pub struct SoftwareInventoryCollection<B: Bmc> {
bmc: NvBmc<B>,
collection: Arc<SoftwareInventoryCollectionSchema>,
read_patch_fn: Option<ReadPatchFn>,
}
impl<B: Bmc> CollectionWithPatch<SoftwareInventoryCollectionSchema, SoftwareInventorySchema, B>
for SoftwareInventoryCollection<B>
{
fn convert_patched(
base: ResourceCollection,
members: Vec<NavProperty<SoftwareInventorySchema>>,
) -> SoftwareInventoryCollectionSchema {
SoftwareInventoryCollectionSchema { base, members }
}
}
impl<B: Bmc> SoftwareInventoryCollection<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
collection_ref: &NavProperty<SoftwareInventoryCollectionSchema>,
read_patch_fn: Option<ReadPatchFn>,
) -> Result<Self, Error<B>> {
let collection =
Self::expand_collection(bmc, collection_ref, read_patch_fn.as_ref(), None).await?;
Ok(Self {
bmc: bmc.clone(),
collection,
read_patch_fn,
})
}
pub(crate) async fn members(&self) -> Result<Vec<SoftwareInventory<B>>, Error<B>> {
let mut items = Vec::new();
for nav in &self.collection.members {
items.push(SoftwareInventory::new(&self.bmc, nav, self.read_patch_fn.as_ref()).await?);
}
Ok(items)
}
}