use std::{fmt::Display, net::IpAddr};
use serde::{Deserialize, Serialize};
use super::plugin::PluginInstanceId;
#[derive(Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
#[serde(default)]
pub struct SgGateway<P = PluginInstanceId> {
pub name: String,
pub parameters: SgParameters,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub listeners: Vec<SgListener>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub plugins: Vec<P>,
}
impl<P> Default for SgGateway<P> {
fn default() -> Self {
Self {
name: Default::default(),
parameters: Default::default(),
listeners: Default::default(),
plugins: Default::default(),
}
}
}
impl<P> SgGateway<P> {
pub fn map_plugins<F, T>(self, f: F) -> SgGateway<T>
where
F: FnMut(P) -> T,
{
SgGateway {
name: self.name,
parameters: self.parameters,
listeners: self.listeners,
plugins: self.plugins.into_iter().map(f).collect(),
}
}
}
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
#[serde(default)]
pub struct SgParameters {
#[serde(skip_serializing_if = "Option::is_none")]
pub redis_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub log_level: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_tls_verification: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub enable_x_request_id: Option<bool>,
}
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
#[serde(default)]
pub struct SgListener {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip: Option<IpAddr>,
pub port: u16,
pub protocol: SgProtocolConfig,
#[serde(skip_serializing_if = "Option::is_none")]
pub hostname: Option<String>,
}
#[non_exhaustive]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
#[serde(rename_all = "lowercase")]
pub enum SgBackendProtocol {
#[default]
Http,
Https,
}
impl Display for SgBackendProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SgBackendProtocol::Http => write!(f, "http"),
SgBackendProtocol::Https { .. } => write!(f, "https"),
}
}
}
#[non_exhaustive]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
#[serde(rename_all = "lowercase", tag = "type")]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
pub enum SgProtocolConfig {
#[default]
Http,
Https {
tls: SgTlsConfig,
},
}
impl Display for SgProtocolConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SgProtocolConfig::Http => write!(f, "http"),
SgProtocolConfig::Https { .. } => write!(f, "https"),
}
}
}
#[derive(Debug, Serialize, PartialEq, Eq, Deserialize, Clone)]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
pub struct SgTlsConfig {
pub mode: SgTlsMode,
pub key: String,
pub cert: String,
pub http2: Option<bool>,
}
#[derive(Debug, Serialize, PartialEq, Deserialize, Clone, Default, Eq, Copy)]
#[cfg_attr(feature = "typegen", derive(ts_rs::TS), ts(export))]
pub enum SgTlsMode {
Terminate,
#[default]
Passthrough,
}
impl From<SgTlsMode> for String {
fn from(value: SgTlsMode) -> Self {
match value {
SgTlsMode::Terminate => "Terminate".to_string(),
SgTlsMode::Passthrough => "Passthrough".to_string(),
}
}
}
impl From<String> for SgTlsMode {
fn from(value: String) -> Self {
match value.to_lowercase().as_str() {
"terminate" => SgTlsMode::Terminate,
"passthrough" => SgTlsMode::Passthrough,
_ => SgTlsMode::Passthrough,
}
}
}
impl From<Option<String>> for SgTlsMode {
fn from(value: Option<String>) -> Self {
SgTlsMode::from(value.unwrap_or_default())
}
}
impl SgTlsMode {
pub fn to_pascal_case(&self) -> &'static str {
match self {
SgTlsMode::Terminate => "Terminate",
SgTlsMode::Passthrough => "Passthrough",
}
}
}