Skip to main content

openleadr_client/
event.rs

1use std::sync::Arc;
2
3use crate::{
4    ClientKind, ClientRef, ReportClient,
5    error::{Error, Result},
6};
7use openleadr_wire::{Event, Report, event::EventRequest, report::ReportRequest};
8
9/// Client to manage the data of a specific event and the reports contained in that event
10///
11/// Can be created by a [`ProgramClient`](crate::ProgramClient)
12/// ```no_run
13/// # use openleadr_client::{BusinessLogic, Client, Filter};
14/// # use openleadr_wire::event::Priority;
15/// let client = Client::<BusinessLogic>::with_url("https://your-vtn.com".try_into().unwrap(), None);
16/// # tokio_test::block_on(async {
17/// let program = client.get_program_by_id(&"program-1".parse().unwrap()).await.unwrap();
18///
19/// // retrieve all events in that specific program
20/// let mut events = program.get_event_list(Filter::none()).await.unwrap();
21/// let mut event = events.remove(0);
22///
23/// // Set event priority to maximum
24/// event.content_mut().priority = Priority::MAX;
25/// event.update().await.unwrap()
26/// # })
27/// ```
28#[derive(Debug, Clone)]
29pub struct EventClient<K> {
30    client: Arc<ClientRef<K>>,
31    data: Event,
32}
33
34impl<K: ClientKind> EventClient<K> {
35    pub(super) fn from_event(client: Arc<ClientRef<K>>, event: Event) -> Self {
36        Self {
37            client,
38            data: event,
39        }
40    }
41
42    /// Get the id of the event
43    pub fn id(&self) -> &openleadr_wire::event::EventId {
44        &self.data.id
45    }
46
47    /// Get the time the event was created on the VTN
48    pub fn created_date_time(&self) -> chrono::DateTime<chrono::Utc> {
49        self.data.created_date_time
50    }
51
52    /// Get the time the event was last modified on the VTN
53    pub fn modification_date_time(&self) -> chrono::DateTime<chrono::Utc> {
54        self.data.modification_date_time
55    }
56
57    /// Read the data of the event
58    pub fn content(&self) -> &EventRequest {
59        &self.data.content
60    }
61
62    /// Modify the data of the event.
63    /// Make sure to call [`update`](Self::update)
64    /// after your modifications to store them on the VTN
65    pub fn content_mut(&mut self) -> &mut EventRequest {
66        &mut self.data.content
67    }
68
69    /// Stores any modifications made to the event content at the server
70    /// and refreshes the locally stored data with the returned VTN data
71    pub async fn update(&mut self) -> Result<()> {
72        self.data = self
73            .client
74            .put(&format!("events/{}", self.id()), &self.data.content)
75            .await?;
76        Ok(())
77    }
78
79    /// Delete the event from the VTN
80    pub async fn delete(self) -> Result<Event> {
81        self.client.delete(&format!("events/{}", self.id())).await
82    }
83
84    /// Create a new report object
85    pub fn new_report(&self, client_name: String) -> ReportRequest {
86        ReportRequest {
87            event_id: self.id().clone(),
88            client_name,
89            report_name: None,
90            payload_descriptors: None,
91            resources: vec![],
92        }
93    }
94
95    /// Create a new report on the VTN.
96    /// The content should be created with [`EventClient::new_report`]
97    /// to automatically insert the correct program ID and event ID
98    pub async fn create_report(&self, report_data: ReportRequest) -> Result<ReportClient<K>> {
99        if &report_data.event_id != self.id() {
100            return Err(Error::InvalidParentObject);
101        }
102
103        let report = self.client.post("reports", &report_data).await?;
104        Ok(ReportClient::from_report(self.client.clone(), report))
105    }
106
107    async fn get_reports_req(
108        &self,
109        client_name: Option<&str>,
110        skip: usize,
111        limit: usize,
112    ) -> Result<Vec<ReportClient<K>>> {
113        let skip_str = skip.to_string();
114        let limit_str = limit.to_string();
115
116        let mut query = vec![
117            ("programID", self.content().program_id.as_str()),
118            ("eventID", self.id().as_str()),
119            ("skip", &skip_str),
120            ("limit", &limit_str),
121        ];
122
123        if let Some(client_name) = client_name {
124            query.push(("clientName", client_name));
125        }
126
127        let reports: Vec<Report> = self.client.get("reports", &query).await?;
128        Ok(reports
129            .into_iter()
130            .map(|report| ReportClient::from_report(self.client.clone(), report))
131            .collect())
132    }
133
134    /// Get all reports from the VTN, possibly filtered by `client_name`, trying to paginate whenever possible
135    pub async fn get_report_list(&self, client_name: Option<&str>) -> Result<Vec<ReportClient<K>>> {
136        self.client
137            .iterate_pages(|skip, limit| self.get_reports_req(client_name, skip, limit))
138            .await
139    }
140}