use chrono::{DateTime, Utc}; use optfield::optfield; use database::generated::entities::{upstream, upstream_target}; use uuid::Uuid; use crate::{ services::nginx::{ builder::{INDENT_SIZE, NginxConfigProvider}, info::upstream_target as upstream_target_info, traits::indentable::Indentable, }, set_if_some, }; #[optfield(pub UpdateUpstreamInfo)] #[derive(Clone)] pub struct UpstreamInfo { pub id: uuid::Uuid, pub name: String, pub protocol: String, pub algorithm: String, pub sticky_session: bool, pub created_by: Option, pub created_at: DateTime, pub updated_at: DateTime, // pub upstream_targets: Vec, } pub struct UpstreamCreateInfo { pub name: String, pub protocol: String, pub algorithm: String, pub sticky_session: bool, pub created_by: Option, // pub upstream_targets: Vec, } impl NginxConfigProvider for UpstreamInfo { fn to_nginx_config(&self, indent: Option) -> String { let targets_config: Vec = self .upstream_targets .iter() .map(|target| target.to_nginx_config(Some(indent.unwrap_or(0) + INDENT_SIZE))) .collect(); format!( "upstream {} {{\n{}\n}}", self.name, targets_config.join("\n".indent(indent.unwrap_or(0) + INDENT_SIZE).as_str()) ) .indent(indent.unwrap_or(0)) } } impl From for (upstream::ActiveModel, Vec) { fn from(val: UpstreamCreateInfo) -> (upstream::ActiveModel, Vec) { let upstream_uuid = Uuid::new_v4(); let upstream = upstream::ActiveModel { id: sea_orm::ActiveValue::Set(upstream_uuid), name: sea_orm::ActiveValue::Set(val.name), protocol: sea_orm::ActiveValue::Set(val.protocol), algorithm: sea_orm::ActiveValue::Set(val.algorithm), sticky_session: sea_orm::ActiveValue::Set(val.sticky_session), created_by: sea_orm::ActiveValue::Set(val.created_by), created_at: sea_orm::ActiveValue::Set(chrono::Utc::now()), updated_at: sea_orm::ActiveValue::Set(chrono::Utc::now()), }; let upstream_targets = val .upstream_targets .into_iter() .map(|target| { let mut active_model: upstream_target::ActiveModel = target.into(); active_model.upstream_id = sea_orm::ActiveValue::Set(upstream_uuid); active_model }) .collect(); (upstream, upstream_targets) } } impl From for UpstreamInfo { fn from(model: upstream::Model) -> Self { Self { id: model.id, name: model.name, protocol: model.protocol, algorithm: model.algorithm, sticky_session: model.sticky_session, created_by: model.created_by, created_at: model.created_at, updated_at: model.updated_at, upstream_targets: Vec::new(), } } } impl From<(upstream::Model, Vec)> for UpstreamInfo { fn from(data: (upstream::Model, Vec)) -> Self { let (upstream_model, upstream_target_models) = data; Self { id: upstream_model.id, name: upstream_model.name, protocol: upstream_model.protocol, algorithm: upstream_model.algorithm, sticky_session: upstream_model.sticky_session, created_by: upstream_model.created_by, created_at: upstream_model.created_at, updated_at: upstream_model.updated_at, upstream_targets: upstream_target_models .into_iter() .map(upstream_target_info::UpstreamTargetInfo::from) .collect(), } } } impl From for (upstream::ActiveModel, Vec) { fn from(val: UpstreamInfo) -> Self { ( upstream::ActiveModel { id: sea_orm::ActiveValue::Set(val.id), name: sea_orm::ActiveValue::Set(val.name), protocol: sea_orm::ActiveValue::Set(val.protocol), algorithm: sea_orm::ActiveValue::Set(val.algorithm), sticky_session: sea_orm::ActiveValue::Set(val.sticky_session), created_by: sea_orm::ActiveValue::Set(val.created_by), created_at: sea_orm::ActiveValue::Set(val.created_at), updated_at: sea_orm::ActiveValue::Set(val.updated_at), }, val.upstream_targets .into_iter() .map(|target| target.into()) .collect(), ) } } impl UpdateUpstreamInfo { pub fn apply_to_model(self, current_model: upstream::Model) -> upstream::ActiveModel { upstream::ActiveModel { id: sea_orm::ActiveValue::Unchanged(current_model.id), name: set_if_some!(self.name), protocol: set_if_some!(self.protocol), algorithm: set_if_some!(self.algorithm), sticky_session: set_if_some!(self.sticky_session), created_by: set_if_some!(if self.created_by.is_some() { Some(self.created_by) } else { None }), created_at: set_if_some!(self.created_at), updated_at: set_if_some!(self.updated_at), } } }