use std::sync::Arc;
use crate::core::Bmc;
use crate::core::EntityTypeRef as _;
use crate::core::NavProperty;
use crate::entity_link::EntityLink;
use crate::schema::task::Task as TaskSchema;
use crate::schema::task_service::TaskService as TaskServiceSchema;
use crate::Error;
use crate::NvBmc;
use crate::Resource;
use crate::ResourceSchema;
use crate::ServiceRoot;
use nv_redfish_core::AsyncTask;
pub type TaskLink<B> = EntityLink<B, TaskSchema>;
pub struct TaskService<B: Bmc> {
data: Arc<TaskServiceSchema>,
bmc: NvBmc<B>,
}
impl<B: Bmc> TaskService<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
root: &ServiceRoot<B>,
) -> Result<Option<Self>, Error<B>> {
let Some(service_ref) = &root.root.tasks else {
return Ok(None);
};
let data = service_ref.get(bmc.as_ref()).await.map_err(Error::Bmc)?;
if data.tasks.is_none() {
return Err(Error::TaskServiceTasksUnavailable);
}
Ok(Some(Self {
data,
bmc: bmc.clone(),
}))
}
#[must_use]
pub fn raw(&self) -> Arc<TaskServiceSchema> {
self.data.clone()
}
pub fn task_link(&self, task: AsyncTask) -> Result<TaskLink<B>, Error<B>> {
let Some(tasks) = self.data.tasks.as_ref() else {
return Err(Error::TaskServiceTasksUnavailable);
};
let task_collection = tasks.odata_id();
let task_location = task.location.0;
if task_collection == &task_location || !task_collection.is_path_prefix(&task_location) {
return Err(Error::TaskLocationNotInTaskService {
task_location,
task_collection: task_collection.clone(),
});
}
let task_ref = NavProperty::new_reference(task_location);
Ok(TaskLink::new(&self.bmc, task_ref))
}
}
impl<B: Bmc> Resource for TaskService<B> {
fn resource_ref(&self) -> &ResourceSchema {
&self.data.as_ref().base
}
}