use crate::types::{Application, ApplicationSecret, ApplicationVolumes, HealthCheck, Metrics, PortMapping};
#[allow(unused_imports)]
use crate::DshApiError;
use itertools::Itertools;
use serde::Serialize;
use std::cmp::Ordering;
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize)]
pub struct Database {}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize)]
pub struct Vhost {}
#[derive(Clone, Debug, Serialize)]
pub struct EnvVarInjection<'a> {
pub id: &'a str,
pub env_var_keys: Vec<&'a str>,
}
impl<'a> EnvVarInjection<'a> {
pub fn new(id: &'a str, env_var_keys: Vec<&'a str>) -> Self {
EnvVarInjection { id, env_var_keys }
}
}
impl Eq for EnvVarInjection<'_> {}
impl PartialEq for EnvVarInjection<'_> {
fn eq(&self, other: &Self) -> bool {
self.id.eq(other.id)
}
}
impl PartialOrd<Self> for EnvVarInjection<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for EnvVarInjection<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(other.id)
}
}
impl<'a> From<(&'a str, Vec<&'a str>)> for EnvVarInjection<'a> {
fn from((id, env_var_keys): (&'a str, Vec<&'a str>)) -> EnvVarInjection<'a> {
EnvVarInjection { id, env_var_keys }
}
}
#[derive(Clone, Debug, Serialize)]
pub struct ApplicationValues<'a, T> {
pub id: &'a str,
pub application: &'a Application,
pub values: Vec<T>,
}
impl<'a, T> ApplicationValues<'a, T> {
pub fn new(id: &'a str, application: &'a Application, values: Vec<T>) -> Self {
Self { id, application, values }
}
}
impl<T> Eq for ApplicationValues<'_, T> {}
impl<T> PartialEq for ApplicationValues<'_, T> {
fn eq(&self, other: &Self) -> bool {
self.id.eq(other.id)
}
}
impl<T> PartialOrd<Self> for ApplicationValues<'_, T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Ord for ApplicationValues<'_, T> {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(other.id)
}
}
#[derive(Clone, Debug, Serialize)]
pub struct ValueApplications<'a, T>
where
T: Eq + Ord,
{
pub value: T,
pub applications: Vec<(&'a str, &'a Application)>,
}
impl<'a, T> ValueApplications<'a, T>
where
T: Eq + Ord,
{
pub fn new(value: T, applications: Vec<(&'a str, &'a Application)>) -> Self {
Self { value, applications }
}
}
impl<T> Eq for ValueApplications<'_, T> where T: Eq + Ord {}
impl<T> PartialEq for ValueApplications<'_, T>
where
T: Eq + Ord,
{
fn eq(&self, other: &Self) -> bool {
self.value.eq(&other.value)
}
}
impl<T> PartialOrd<Self> for ValueApplications<'_, T>
where
T: Eq + Ord,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Ord for ValueApplications<'_, T>
where
T: Eq + Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct ApplicationDiff {
pub cpus: Option<(f64, f64)>,
pub env: Option<(HashMap<String, String>, HashMap<String, String>)>,
pub exposed_ports: Option<(HashMap<String, PortMapping>, HashMap<String, PortMapping>)>,
pub health_check: Option<(Option<HealthCheck>, Option<HealthCheck>)>,
pub image: Option<(String, String)>,
pub instances: Option<(u64, u64)>,
pub mem: Option<(u64, u64)>,
pub metrics: Option<(Option<Metrics>, Option<Metrics>)>,
pub needs_token: Option<(bool, bool)>,
pub readable_streams: Option<(Vec<String>, Vec<String>)>,
pub secrets: Option<(Vec<ApplicationSecret>, Vec<ApplicationSecret>)>,
pub single_instance: Option<(bool, bool)>,
pub spread_group: Option<(Option<String>, Option<String>)>,
pub topics: Option<(Vec<String>, Vec<String>)>,
pub user: Option<(String, String)>,
pub volumes: Option<(HashMap<String, ApplicationVolumes>, HashMap<String, ApplicationVolumes>)>,
pub writable_streams: Option<(Vec<String>, Vec<String>)>,
}
impl ApplicationDiff {
pub fn differences_between_applications(baseline: &Application, sample: &Application) -> ApplicationDiff {
ApplicationDiff {
cpus: if baseline.cpus == sample.cpus { None } else { Some((baseline.cpus, sample.cpus)) },
env: if baseline.env == sample.env { None } else { Some((baseline.env.clone(), sample.env.clone())) },
exposed_ports: if baseline.exposed_ports == sample.exposed_ports.clone() { None } else { Some((baseline.exposed_ports.clone(), sample.exposed_ports.clone())) },
health_check: if baseline.health_check == sample.health_check { None } else { Some((baseline.health_check.clone(), sample.health_check.clone())) },
image: if baseline.image == sample.image.clone() { None } else { Some((baseline.image.clone(), sample.image.clone())) },
instances: if baseline.instances == sample.instances { None } else { Some((baseline.instances, sample.instances)) },
mem: if baseline.mem == sample.mem { None } else { Some((baseline.mem, sample.mem)) },
metrics: if baseline.metrics == sample.metrics { None } else { Some((baseline.metrics.clone(), sample.metrics.clone())) },
needs_token: if baseline.needs_token == sample.needs_token { None } else { Some((baseline.needs_token, sample.needs_token)) },
readable_streams: if baseline.readable_streams == sample.readable_streams { None } else { Some((baseline.readable_streams.clone(), sample.readable_streams.clone())) },
secrets: if baseline.secrets == sample.secrets { None } else { Some((baseline.secrets.clone(), sample.secrets.clone())) },
single_instance: if baseline.single_instance == sample.single_instance { None } else { Some((baseline.single_instance, sample.single_instance)) },
spread_group: if baseline.spread_group == sample.spread_group { None } else { Some((baseline.spread_group.clone(), sample.spread_group.clone())) },
topics: if baseline.topics == sample.topics { None } else { Some((baseline.topics.clone(), sample.topics.clone())) },
user: if baseline.user == sample.user { None } else { Some((baseline.user.clone(), sample.user.clone())) },
volumes: if baseline.volumes == sample.volumes { None } else { Some((baseline.volumes.clone(), sample.volumes.clone())) },
writable_streams: if baseline.writable_streams == sample.writable_streams { None } else { Some((baseline.writable_streams.clone(), sample.writable_streams.clone())) },
}
}
pub fn is_empty(&self) -> bool {
self.cpus.is_none()
&& self.env.is_none()
&& self.exposed_ports.is_none()
&& self.health_check.is_none()
&& self.image.is_none()
&& self.instances.is_none()
&& self.mem.is_none()
&& self.metrics.is_none()
&& self.needs_token.is_none()
&& self.readable_streams.is_none()
&& self.secrets.is_none()
&& self.single_instance.is_none()
&& self.spread_group.is_none()
&& self.topics.is_none()
&& self.user.is_none()
&& self.volumes.is_none()
&& self.writable_streams.is_none()
}
pub fn differences(&self) -> Vec<(String, String)> {
vec![
self.env.as_ref().map(|value| ("env".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.exposed_ports
.as_ref()
.map(|value| ("exposed ports".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.health_check
.as_ref()
.map(|value| ("healt check".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.image.as_ref().map(|value| ("image".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.instances
.map(|value| ("number of instances".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.mem.map(|value| ("memory".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.metrics.as_ref().map(|value| ("metrics".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.needs_token.map(|value| ("needs token".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.readable_streams
.as_ref()
.map(|value| ("readable streams".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.secrets.as_ref().map(|value| ("secrets".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.single_instance
.map(|value| ("single instance".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.spread_group
.as_ref()
.map(|value| ("spread group".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.topics.as_ref().map(|value| ("topics".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.user.as_ref().map(|value| ("user".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self.volumes.as_ref().map(|value| ("volumes".to_string(), format!("{:?} / {:?}", value.0, value.1))),
self
.writable_streams
.as_ref()
.map(|value| ("writable streams".to_string(), format!("{:?} / {:?}", value.0, value.1))),
]
.iter()
.flatten()
.collect_vec()
.iter()
.map(|p| p.to_owned().to_owned())
.collect_vec()
}
}