use std::net::SocketAddr;
use std::path::PathBuf;
use std::time::Duration;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct GrpcConfig {
pub listen: SocketAddr,
#[serde(default)]
pub proto: Vec<String>,
#[serde(with = "human_bytes")]
pub max_recv_message_size: usize,
#[serde(with = "human_bytes")]
pub max_send_message_size: usize,
#[serde(
default,
with = "humantime_serde",
skip_serializing_if = "Option::is_none"
)]
pub timeout: Option<Duration>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_concurrent_streams: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub keepalive: Option<KeepaliveConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tls: Option<TlsConfig>,
#[serde(default)]
pub compression: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TlsConfig {
pub cert: PathBuf,
pub key: PathBuf,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeepaliveConfig {
#[serde(with = "humantime_serde")]
pub interval: Duration,
#[serde(with = "humantime_serde")]
pub timeout: Duration,
}
impl Default for GrpcConfig {
fn default() -> Self {
Self {
listen: "0.0.0.0:50051".parse().unwrap(),
proto: vec![],
max_recv_message_size: 4 * 1024 * 1024, max_send_message_size: 4 * 1024 * 1024, timeout: None,
max_concurrent_streams: None,
keepalive: None,
tls: None,
compression: false,
}
}
}
pub fn parse_byte_size(s: &str) -> Result<usize, String> {
let s = s.trim().to_lowercase();
if let Ok(n) = s.parse::<usize>() {
return Ok(n);
}
let (num_part, multiplier) = if let Some(n) = s.strip_suffix("gib") {
(n, 1024 * 1024 * 1024)
} else if let Some(n) = s.strip_suffix("gb") {
(n, 1024 * 1024 * 1024)
} else if let Some(n) = s.strip_suffix("mib") {
(n, 1024 * 1024)
} else if let Some(n) = s.strip_suffix("mb") {
(n, 1024 * 1024)
} else if let Some(n) = s.strip_suffix("kib") {
(n, 1024)
} else if let Some(n) = s.strip_suffix("kb") {
(n, 1024)
} else if let Some(n) = s.strip_suffix("b") {
(n, 1)
} else {
return Err(format!("invalid byte size: {s:?}"));
};
let num: usize = num_part
.trim()
.parse()
.map_err(|_| format!("invalid byte size number: {num_part:?}"))?;
Ok(num * multiplier)
}
mod human_bytes {
use serde::{Deserialize, Deserializer, Serializer, de};
pub fn serialize<S: Serializer>(value: &usize, ser: S) -> Result<S::Ok, S::Error> {
ser.serialize_u64(*value as u64)
}
pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<usize, D::Error> {
#[derive(Deserialize)]
#[serde(untagged)]
enum ByteSize {
Str(String),
Num(usize),
}
match ByteSize::deserialize(de)? {
ByteSize::Num(n) => Ok(n),
ByteSize::Str(s) => super::parse_byte_size(&s).map_err(de::Error::custom),
}
}
}