use crate::Error;
use crate::NvBmc;
use nv_redfish_core::Bmc;
use nv_redfish_core::Deletable;
use nv_redfish_core::EntityTypeRef;
use nv_redfish_core::ModificationResponse;
use nv_redfish_core::NavProperty;
use nv_redfish_core::ODataId;
use serde::Deserialize;
use std::future::Future;
use std::sync::Arc;
pub struct EntityLink<B: Bmc, T: EntityTypeRef> {
bmc: NvBmc<B>,
nav: NavProperty<T>,
}
impl<B: Bmc, T: EntityTypeRef> EntityLink<B, T> {
pub(crate) fn new(bmc: &NvBmc<B>, nav: NavProperty<T>) -> Self {
Self {
bmc: bmc.clone(),
nav,
}
}
#[must_use]
pub fn odata_id(&self) -> &ODataId {
self.nav.id()
}
#[must_use]
pub const fn nav(&self) -> &NavProperty<T> {
&self.nav
}
}
impl<B, T> EntityLink<B, T>
where
B: Bmc,
T: EntityTypeRef + for<'de> Deserialize<'de> + Send + Sync + 'static,
{
pub async fn fetch(&self) -> Result<Arc<T>, Error<B>> {
self.nav.get(self.bmc.as_ref()).await.map_err(Error::Bmc)
}
pub async fn upgrade<W>(&self) -> Result<W, Error<B>>
where
W: FromLink<B, Schema = T>,
{
W::from_link(&self.bmc, &self.nav).await
}
}
impl<B, T> EntityLink<B, T>
where
B: Bmc,
T: Deletable,
{
pub async fn delete(&self) -> Result<ModificationResponse<T>, Error<B>> {
self.bmc
.as_ref()
.delete(self.odata_id())
.await
.map_err(Error::Bmc)
}
}
pub trait FromLink<B: Bmc>: Sized {
type Schema: EntityTypeRef + for<'de> Deserialize<'de> + Send + Sync + 'static;
fn from_link(
bmc: &NvBmc<B>,
nav: &NavProperty<Self::Schema>,
) -> impl Future<Output = Result<Self, Error<B>>> + Send;
}