use reqwest::{Client, Url};
use serde::{Deserialize, Serialize};
use crate::ddi::client::Error;
use crate::ddi::deployment_base::{Chunk, Deployment};
#[derive(Debug)]
#[allow(dead_code)]
pub struct ConfirmationRequest {
client: Client,
url: String,
details: Vec<String>,
}
impl ConfirmationRequest {
pub(crate) fn new(client: Client, url: String) -> Self {
Self {
client,
url,
details: vec![],
}
}
pub async fn confirm(self) -> Result<(), Error> {
let confirmation = Confirmation::new(ConfirmationResponse::Confirmed, 1);
let mut url: Url = self.url.parse()?;
{
let mut paths = url
.path_segments_mut()
.map_err(|_| url::ParseError::SetHostOnCannotBeABaseUrl)?;
paths.push("feedback");
}
url.set_query(None);
let reply = self
.client
.post(url.to_string())
.json(&confirmation)
.send()
.await?;
reply.error_for_status_ref()?;
Ok(())
}
pub async fn decline(self) -> Result<(), Error> {
let confirmation = Confirmation::new(ConfirmationResponse::Denied, -1);
let mut url: Url = self.url.parse()?;
{
let mut paths = url
.path_segments_mut()
.map_err(|_| url::ParseError::SetHostOnCannotBeABaseUrl)?;
paths.push("feedback");
}
url.set_query(None);
let reply = self
.client
.post(url.to_string())
.json(&confirmation)
.send()
.await?;
reply.error_for_status_ref()?;
Ok(())
}
pub async fn update_info(&self) -> Result<ConfirmationInfo, Error> {
let reply = self.client.get(&self.url).send().await?;
reply.error_for_status_ref()?;
let reply: Reply = reply.json().await?;
Ok(ConfirmationInfo {
reply,
client: self.client.clone(),
})
}
pub async fn metadata(&self) -> Result<Vec<(String, String)>, Error> {
let client = self.client.clone();
let update = self.update_info().await?.reply;
let chunks: Vec<Chunk> = update
.confirmation
.chunks
.iter()
.map(move |c| Chunk::new(c, client.clone()))
.collect();
let metadata = chunks
.iter()
.flat_map(|c| c.metadata().collect::<Vec<(&str, &str)>>())
.map(|(k, v): (&str, &str)| (k.to_string(), v.to_string()))
.collect();
Ok(metadata)
}
}
#[derive(Debug)]
pub struct ConfirmationInfo {
client: Client,
reply: Reply,
}
impl ConfirmationInfo {
pub fn metadata(&self) -> Vec<(String, String)> {
let chunks: Vec<Chunk> = self
.reply
.confirmation
.chunks
.iter()
.map(move |c| Chunk::new(c, self.client.clone()))
.collect();
let metadata = chunks
.iter()
.flat_map(|c| c.metadata().collect::<Vec<(&str, &str)>>())
.map(|(k, v): (&str, &str)| (k.to_string(), v.to_string()))
.collect();
metadata
}
pub fn action_id(&self) -> &str {
&self.reply.id
}
}
#[derive(Debug, Deserialize)]
pub(crate) struct Reply {
id: String,
confirmation: Deployment,
}
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ConfirmationResponse {
Confirmed,
Denied,
}
#[derive(Debug, Serialize)]
pub struct Confirmation {
confirmation: ConfirmationResponse,
code: i32,
details: Vec<String>,
}
impl Confirmation {
pub fn new(confirmation: ConfirmationResponse, code: i32) -> Self {
Self {
confirmation,
code,
details: vec![],
}
}
}