use crate::{
error::{Error, Result},
Client, EventClient, EventContent, Filter, PaginationOptions, ProgramContent, ProgramId,
Timeline,
};
use openleadr_wire::{
event::{EventInterval, Priority},
Program,
};
#[derive(Debug, Clone)]
pub struct ProgramClient {
client: Client,
data: Program,
}
impl ProgramClient {
pub(super) fn from_program(client: Client, program: Program) -> Self {
Self {
client,
data: program,
}
}
pub fn id(&self) -> &ProgramId {
&self.data.id
}
pub fn created_date_time(&self) -> chrono::DateTime<chrono::Utc> {
self.data.created_date_time
}
pub fn modification_date_time(&self) -> chrono::DateTime<chrono::Utc> {
self.data.modification_date_time
}
pub fn content(&self) -> &ProgramContent {
&self.data.content
}
pub fn content_mut(&mut self) -> &mut ProgramContent {
&mut self.data.content
}
pub async fn update(&mut self) -> Result<()> {
self.data = self
.client
.client_ref
.put(&format!("programs/{}", self.id()), &self.data.content)
.await?;
Ok(())
}
pub async fn delete(self) -> Result<Program> {
self.client
.client_ref
.delete(&format!("programs/{}", self.id()))
.await
}
pub async fn create_event(&self, event_data: EventContent) -> Result<EventClient> {
if &event_data.program_id != self.id() {
return Err(Error::InvalidParentObject);
}
let event = self.client.client_ref.post("events", &event_data).await?;
Ok(EventClient::from_event(
self.client.client_ref.clone(),
event,
))
}
pub fn new_event(&self, intervals: Vec<EventInterval>) -> EventContent {
EventContent {
program_id: self.id().clone(),
event_name: None,
priority: Priority::UNSPECIFIED,
targets: None,
report_descriptors: None,
payload_descriptors: None,
interval_period: None,
intervals,
}
}
pub async fn get_events_request(
&self,
filter: Filter<'_, impl AsRef<str>>,
pagination: PaginationOptions,
) -> Result<Vec<EventClient>> {
self.client
.get_events(Some(self.id()), filter, pagination)
.await
}
pub async fn get_event_list(
&self,
filter: Filter<'_, impl AsRef<str> + Clone>,
) -> Result<Vec<EventClient>> {
self.client.get_event_list(Some(self.id()), filter).await
}
pub async fn get_timeline(
&self,
filter: Filter<'_, impl AsRef<str> + Clone>,
) -> Result<Timeline> {
let events = self.get_event_list(filter).await?;
let events = events.iter().map(|e| e.content()).collect();
Timeline::from_events(&self.data, events).ok_or(Error::InvalidInterval)
}
}