use crate::{
Client, ClientKind, EventClient, Filter, PaginationOptions, ProgramId, ProgramRequest,
Timeline,
error::{Error, Result},
};
use openleadr_wire::{
Program,
event::{EventInterval, EventRequest, Priority},
};
#[derive(Debug, Clone)]
pub struct ProgramClient<K> {
client: Client<K>,
data: Program,
}
impl<K: ClientKind> ProgramClient<K> {
pub(super) fn from_program(client: Client<K>, 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) -> &ProgramRequest {
&self.data.content
}
pub fn content_mut(&mut self) -> &mut ProgramRequest {
&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: EventRequest) -> Result<EventClient<K>> {
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>) -> EventRequest {
EventRequest {
program_id: self.id().clone(),
event_name: None,
priority: Priority::UNSPECIFIED,
targets: vec![],
report_descriptors: None,
payload_descriptors: None,
interval_period: None,
duration: None,
intervals: Some(intervals),
}
}
pub async fn get_events_request(
&self,
filter: Filter<'_, impl AsRef<str>>,
pagination: PaginationOptions,
) -> Result<Vec<EventClient<K>>> {
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<K>>> {
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)
}
}