1use crate::{
2 BusinessLogic, ClientKind, ClientRef, Error, Result, VirtualEndNode, resource::ResourceClient,
3};
4use chrono::{DateTime, Utc};
5use openleadr_wire::{
6 Ven,
7 resource::{BlResourceRequest, Resource, ResourceId, ResourceRequest, VenResourceRequest},
8 target::Target,
9 values_map::ValuesMap,
10 ven::{BlVenRequest, VenId, VenRequest},
11};
12use std::{fmt::Display, sync::Arc};
13
14#[derive(Debug, Clone)]
16pub struct VenClient<K> {
17 client: Arc<ClientRef<K>>,
18 data: Ven,
19}
20
21impl VenClient<BusinessLogic> {
22 pub async fn create_resource<S: Display>(
24 &self,
25 name: S,
26 attributes: Option<Vec<ValuesMap>>,
27 targets: Vec<Target>,
28 ) -> Result<ResourceClient<BusinessLogic>> {
29 let resource = self
30 .client
31 .post(
32 "resources",
33 &ResourceRequest::BlResourceRequest(BlResourceRequest {
34 targets,
35 resource_name: name.to_string(),
36 ven_id: self.data.id.clone(),
37 attributes,
38 }),
39 )
40 .await?;
41 Ok(ResourceClient::from_resource(
42 Arc::clone(&self.client),
43 resource,
44 ))
45 }
46}
47
48impl VenClient<VirtualEndNode> {
49 pub async fn create_resource<S: Display>(
51 &self,
52 name: S,
53 attributes: Option<Vec<ValuesMap>>,
54 ) -> Result<ResourceClient<VirtualEndNode>> {
55 let resource = self
56 .client
57 .post(
58 "resources",
59 &ResourceRequest::VenResourceRequest(VenResourceRequest {
60 resource_name: name.to_string(),
61 attributes,
62 }),
63 )
64 .await?;
65 Ok(ResourceClient::from_resource(
66 Arc::clone(&self.client),
67 resource,
68 ))
69 }
70}
71
72impl<K: ClientKind> VenClient<K> {
73 pub(super) fn from_ven(client: Arc<ClientRef<K>>, data: Ven) -> Self {
74 Self { client, data }
75 }
76
77 pub fn id(&self) -> &VenId {
79 &self.data.id
80 }
81
82 pub fn created_date_time(&self) -> DateTime<Utc> {
84 self.data.created_date_time
85 }
86
87 pub fn modification_date_time(&self) -> DateTime<Utc> {
89 self.data.modification_date_time
90 }
91
92 pub fn content(&self) -> &BlVenRequest {
94 &self.data.content
95 }
96
97 pub fn content_mut(&mut self) -> &mut BlVenRequest {
101 &mut self.data.content
102 }
103
104 pub async fn update(&mut self) -> Result<()> {
107 self.data = self
108 .client
109 .put(
110 &format!("vens/{}", self.id()),
111 &VenRequest::BlVenRequest(self.data.content.clone()),
112 )
113 .await?;
114 Ok(())
115 }
116
117 pub async fn delete(self) -> Result<Ven> {
122 self.client.delete(&format!("vens/{}", self.id())).await
123 }
124
125 async fn get_resources_req(
126 &self,
127 resource_name: Option<&str>,
128 skip: usize,
129 limit: usize,
130 ) -> Result<Vec<ResourceClient<K>>> {
131 let skip_str = skip.to_string();
132 let limit_str = limit.to_string();
133
134 let mut query: Vec<(&str, &str)> = vec![("skip", &skip_str), ("limit", &limit_str)];
135
136 if let Some(resource_name) = resource_name {
137 query.push(("resourceName", resource_name));
138 }
139
140 let resources: Vec<Resource> = self.client.get("/resources", &query).await?;
141 Ok(resources
142 .into_iter()
143 .map(|resource| ResourceClient::from_resource(Arc::clone(&self.client), resource))
144 .collect())
145 }
146
147 pub async fn get_all_resources(
151 &self,
152 resource_name: Option<&str>,
153 ) -> Result<Vec<ResourceClient<K>>> {
154 self.client
155 .iterate_pages(|skip, limit| self.get_resources_req(resource_name, skip, limit))
156 .await
157 }
158
159 pub async fn get_resource_by_id(&self, id: &ResourceId) -> Result<ResourceClient<K>> {
161 let resource = self.client.get(&format!("resources/{}", id), &[]).await?;
162 Ok(ResourceClient::from_resource(
163 Arc::clone(&self.client),
164 resource,
165 ))
166 }
167
168 pub async fn get_resource_by_name(&self, name: &str) -> Result<ResourceClient<K>> {
171 let mut resources: Vec<Resource> = self
172 .client
173 .get("resources", &[("resourceName", name)])
174 .await?;
175 match resources[..] {
176 [] => Err(Error::ObjectNotFound),
177 [_] => Ok(ResourceClient::from_resource(
178 Arc::clone(&self.client),
179 resources.remove(0),
180 )),
181 [..] => Err(Error::DuplicateObject),
182 }
183 }
184}