use crate::{
BusinessLogic, ClientKind, ClientRef, Error, Result, VirtualEndNode, resource::ResourceClient,
};
use chrono::{DateTime, Utc};
use openleadr_wire::{
Ven,
resource::{BlResourceRequest, Resource, ResourceId, ResourceRequest, VenResourceRequest},
target::Target,
values_map::ValuesMap,
ven::{BlVenRequest, VenId, VenRequest},
};
use std::{fmt::Display, sync::Arc};
#[derive(Debug, Clone)]
pub struct VenClient<K> {
client: Arc<ClientRef<K>>,
data: Ven,
}
impl VenClient<BusinessLogic> {
pub async fn create_resource<S: Display>(
&self,
name: S,
attributes: Option<Vec<ValuesMap>>,
targets: Vec<Target>,
) -> Result<ResourceClient<BusinessLogic>> {
let resource = self
.client
.post(
"resources",
&ResourceRequest::BlResourceRequest(BlResourceRequest {
targets,
resource_name: name.to_string(),
ven_id: self.data.id.clone(),
attributes,
}),
)
.await?;
Ok(ResourceClient::from_resource(
Arc::clone(&self.client),
resource,
))
}
}
impl VenClient<VirtualEndNode> {
pub async fn create_resource<S: Display>(
&self,
name: S,
attributes: Option<Vec<ValuesMap>>,
) -> Result<ResourceClient<VirtualEndNode>> {
let resource = self
.client
.post(
"resources",
&ResourceRequest::VenResourceRequest(VenResourceRequest {
resource_name: name.to_string(),
attributes,
}),
)
.await?;
Ok(ResourceClient::from_resource(
Arc::clone(&self.client),
resource,
))
}
}
impl<K: ClientKind> VenClient<K> {
pub(super) fn from_ven(client: Arc<ClientRef<K>>, data: Ven) -> Self {
Self { client, data }
}
pub fn id(&self) -> &VenId {
&self.data.id
}
pub fn created_date_time(&self) -> DateTime<Utc> {
self.data.created_date_time
}
pub fn modification_date_time(&self) -> DateTime<Utc> {
self.data.modification_date_time
}
pub fn content(&self) -> &BlVenRequest {
&self.data.content
}
pub fn content_mut(&mut self) -> &mut BlVenRequest {
&mut self.data.content
}
pub async fn update(&mut self) -> Result<()> {
self.data = self
.client
.put(
&format!("vens/{}", self.id()),
&VenRequest::BlVenRequest(self.data.content.clone()),
)
.await?;
Ok(())
}
pub async fn delete(self) -> Result<Ven> {
self.client.delete(&format!("vens/{}", self.id())).await
}
async fn get_resources_req(
&self,
resource_name: Option<&str>,
skip: usize,
limit: usize,
) -> Result<Vec<ResourceClient<K>>> {
let skip_str = skip.to_string();
let limit_str = limit.to_string();
let mut query: Vec<(&str, &str)> = vec![("skip", &skip_str), ("limit", &limit_str)];
if let Some(resource_name) = resource_name {
query.push(("resourceName", resource_name));
}
let resources: Vec<Resource> = self.client.get("/resources", &query).await?;
Ok(resources
.into_iter()
.map(|resource| ResourceClient::from_resource(Arc::clone(&self.client), resource))
.collect())
}
pub async fn get_all_resources(
&self,
resource_name: Option<&str>,
) -> Result<Vec<ResourceClient<K>>> {
self.client
.iterate_pages(|skip, limit| self.get_resources_req(resource_name, skip, limit))
.await
}
pub async fn get_resource_by_id(&self, id: &ResourceId) -> Result<ResourceClient<K>> {
let resource = self.client.get(&format!("resources/{}", id), &[]).await?;
Ok(ResourceClient::from_resource(
Arc::clone(&self.client),
resource,
))
}
pub async fn get_resource_by_name(&self, name: &str) -> Result<ResourceClient<K>> {
let mut resources: Vec<Resource> = self
.client
.get("resources", &[("resourceName", name)])
.await?;
match resources[..] {
[] => Err(Error::ObjectNotFound),
[_] => Ok(ResourceClient::from_resource(
Arc::clone(&self.client),
resources.remove(0),
)),
[..] => Err(Error::DuplicateObject),
}
}
}