use crate::bmc_quirks::BmcQuirks;
use crate::core::Bmc;
use crate::core::NavProperty;
use crate::core::ODataId;
use crate::schema::redfish::service_root::ServiceRoot as SchemaServiceRoot;
use crate::Error;
use crate::NvBmc;
use crate::ProtocolFeatures;
use crate::Resource;
use crate::ResourceSchema;
use std::sync::Arc;
use tagged_types::TaggedType;
#[cfg(feature = "accounts")]
use crate::account::AccountService;
#[cfg(feature = "chassis")]
use crate::chassis::ChassisCollection;
#[cfg(feature = "computer-systems")]
use crate::computer_system::SystemCollection;
#[cfg(feature = "event-service")]
use crate::event_service::EventService;
#[cfg(feature = "managers")]
use crate::manager::ManagerCollection;
#[cfg(feature = "oem-hpe")]
use crate::oem::hpe::HpeiLoServiceExt;
#[cfg(feature = "telemetry-service")]
use crate::telemetry_service::TelemetryService;
#[cfg(feature = "update-service")]
use crate::update_service::UpdateService;
#[cfg(feature = "session-service")]
use crate::session_service::SessionService;
pub type Vendor<T> = TaggedType<T, VendorTag>;
#[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 VendorTag {}
pub type Product<T> = TaggedType<T, ProductTag>;
#[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 ProductTag {}
pub type RedfishVersion<'a> = TaggedType<&'a str, RedfishVersionTag>;
#[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 RedfishVersionTag {}
#[derive(Clone)]
pub struct ServiceRoot<B: Bmc> {
pub root: Arc<SchemaServiceRoot>,
#[allow(dead_code)] bmc: NvBmc<B>,
}
impl<B: Bmc> ServiceRoot<B> {
pub async fn new(bmc: Arc<B>) -> Result<Self, Error<B>> {
let root = NavProperty::<SchemaServiceRoot>::new_reference(ODataId::service_root())
.get(bmc.as_ref())
.await
.map_err(Error::Bmc)?;
let quirks = BmcQuirks::new(&root);
let mut protocol_features = root
.protocol_features_supported
.as_ref()
.map(ProtocolFeatures::new)
.unwrap_or_default();
if quirks.expand_is_not_working_properly() {
protocol_features.expand.expand_all = false;
protocol_features.expand.no_links = false;
}
let bmc = NvBmc::new(bmc, protocol_features, quirks);
Ok(Self { root, bmc })
}
#[must_use]
pub fn replace_bmc(self, bmc: Arc<B>) -> Self {
let root = self.root;
let bmc = self.bmc.replace_bmc(bmc);
Self { root, bmc }
}
#[must_use]
pub fn restrict_expand(self) -> Self {
let root = self.root;
let bmc = self.bmc.restrict_expand();
Self { root, bmc }
}
pub fn vendor(&self) -> Option<Vendor<&str>> {
self.root
.vendor
.as_ref()
.and_then(Option::as_ref)
.map(String::as_str)
.map(Vendor::new)
}
pub fn product(&self) -> Option<Product<&str>> {
self.root
.product
.as_ref()
.and_then(Option::as_ref)
.map(String::as_str)
.map(Product::new)
}
pub fn redfish_version(&self) -> Option<RedfishVersion<'_>> {
self.root
.redfish_version
.as_deref()
.map(RedfishVersion::new)
}
#[cfg(feature = "accounts")]
pub async fn account_service(&self) -> Result<Option<AccountService<B>>, Error<B>> {
AccountService::new(&self.bmc, self).await
}
#[cfg(feature = "chassis")]
pub async fn chassis(&self) -> Result<Option<ChassisCollection<B>>, Error<B>> {
ChassisCollection::new(&self.bmc, self).await
}
#[cfg(feature = "computer-systems")]
pub async fn systems(&self) -> Result<Option<SystemCollection<B>>, Error<B>> {
SystemCollection::new(&self.bmc, self).await
}
#[cfg(feature = "update-service")]
pub async fn update_service(&self) -> Result<Option<UpdateService<B>>, Error<B>> {
UpdateService::new(&self.bmc, self).await
}
#[cfg(feature = "event-service")]
pub async fn event_service(&self) -> Result<Option<EventService<B>>, Error<B>> {
EventService::new(&self.bmc, self).await
}
#[cfg(feature = "telemetry-service")]
pub async fn telemetry_service(&self) -> Result<Option<TelemetryService<B>>, Error<B>> {
TelemetryService::new(&self.bmc, self).await
}
#[cfg(feature = "session-service")]
pub async fn session_service(&self) -> Result<Option<SessionService<B>>, Error<B>> {
SessionService::new(&self.bmc, self).await
}
#[cfg(feature = "managers")]
pub async fn managers(&self) -> Result<Option<ManagerCollection<B>>, Error<B>> {
ManagerCollection::new(&self.bmc, self).await
}
#[cfg(feature = "oem-hpe")]
pub fn oem_hpe_ilo_service_ext(&self) -> Result<Option<HpeiLoServiceExt<B>>, Error<B>> {
HpeiLoServiceExt::new(&self.root)
}
}
impl<B: Bmc> Resource for ServiceRoot<B> {
fn resource_ref(&self) -> &ResourceSchema {
&self.root.as_ref().base
}
}