use std::time::Duration;
#[derive(Debug, Clone, Default)]
pub struct TlsConfig {
pub ca_cert_pem: Option<Vec<u8>>,
pub client_cert_pem: Option<Vec<u8>>,
pub client_key_pem: Option<Vec<u8>>,
pub skip_verify: bool,
pub domain_name: Option<String>,
}
impl TlsConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_ca_cert_pem(mut self, pem: Vec<u8>) -> Self {
self.ca_cert_pem = Some(pem);
self
}
pub fn with_client_cert_pem(mut self, cert_pem: Vec<u8>, key_pem: Vec<u8>) -> Self {
self.client_cert_pem = Some(cert_pem);
self.client_key_pem = Some(key_pem);
self
}
pub fn with_skip_verify(mut self) -> Self {
self.skip_verify = true;
self
}
pub fn with_domain_name(mut self, name: impl Into<String>) -> Self {
self.domain_name = Some(name.into());
self
}
}
#[derive(Debug, Clone)]
pub struct ClientOptions {
pub max_json_payload_size: usize,
pub max_identifier_length: usize,
pub tls: Option<TlsConfig>,
pub connect_timeout: Option<Duration>,
pub max_grpc_message_size: Option<usize>,
pub keepalive_interval: Option<Duration>,
pub keepalive_timeout: Option<Duration>,
}
impl Default for ClientOptions {
fn default() -> Self {
Self {
max_json_payload_size: 64 * 1024 * 1024, max_identifier_length: 1_024,
tls: None,
connect_timeout: None,
max_grpc_message_size: None,
keepalive_interval: None,
keepalive_timeout: None,
}
}
}
impl ClientOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_max_json_payload_size(mut self, limit: usize) -> Self {
self.max_json_payload_size = limit;
self
}
pub fn with_max_identifier_length(mut self, limit: usize) -> Self {
self.max_identifier_length = limit;
self
}
pub fn with_tls(mut self, tls: TlsConfig) -> Self {
self.tls = Some(tls);
self
}
pub fn with_connect_timeout(mut self, timeout: Duration) -> Self {
self.connect_timeout = Some(timeout);
self
}
pub fn with_max_grpc_message_size(mut self, size: usize) -> Self {
self.max_grpc_message_size = Some(size);
self
}
pub fn with_keepalive_interval(mut self, interval: Duration) -> Self {
self.keepalive_interval = Some(interval);
self
}
pub fn with_keepalive_timeout(mut self, timeout: Duration) -> Self {
self.keepalive_timeout = Some(timeout);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tls_config_defaults() {
let tls = TlsConfig::new();
assert!(tls.ca_cert_pem.is_none());
assert!(tls.client_cert_pem.is_none());
assert!(tls.client_key_pem.is_none());
assert!(!tls.skip_verify);
assert!(tls.domain_name.is_none());
}
#[test]
fn tls_config_with_ca_cert_pem() {
let tls = TlsConfig::new().with_ca_cert_pem(b"ca-data".to_vec());
assert_eq!(tls.ca_cert_pem.as_deref(), Some(b"ca-data".as_slice()));
}
#[test]
fn tls_config_with_client_cert_pem() {
let tls = TlsConfig::new().with_client_cert_pem(b"cert".to_vec(), b"key".to_vec());
assert_eq!(tls.client_cert_pem.as_deref(), Some(b"cert".as_slice()));
assert_eq!(tls.client_key_pem.as_deref(), Some(b"key".as_slice()));
}
#[test]
fn tls_config_with_skip_verify() {
let tls = TlsConfig::new().with_skip_verify();
assert!(tls.skip_verify);
}
#[test]
fn tls_config_with_domain_name() {
let tls = TlsConfig::new().with_domain_name("example.com");
assert_eq!(tls.domain_name.as_deref(), Some("example.com"));
}
#[test]
fn client_options_defaults() {
let opts = ClientOptions::default();
assert_eq!(opts.max_json_payload_size, 64 * 1024 * 1024);
assert_eq!(opts.max_identifier_length, 1024);
assert!(opts.tls.is_none());
assert!(opts.connect_timeout.is_none());
assert!(opts.max_grpc_message_size.is_none());
assert!(opts.keepalive_interval.is_none());
assert!(opts.keepalive_timeout.is_none());
}
#[test]
fn client_options_with_max_json_payload_size() {
let opts = ClientOptions::new().with_max_json_payload_size(1024);
assert_eq!(opts.max_json_payload_size, 1024);
}
#[test]
fn client_options_with_max_identifier_length() {
let opts = ClientOptions::new().with_max_identifier_length(256);
assert_eq!(opts.max_identifier_length, 256);
}
#[test]
fn client_options_with_tls() {
let opts = ClientOptions::new().with_tls(TlsConfig::default());
assert!(opts.tls.is_some());
}
#[test]
fn client_options_with_connect_timeout() {
let opts = ClientOptions::new().with_connect_timeout(Duration::from_secs(5));
assert_eq!(opts.connect_timeout, Some(Duration::from_secs(5)));
}
#[test]
fn client_options_with_max_grpc_message_size() {
let opts = ClientOptions::new().with_max_grpc_message_size(16 * 1024 * 1024);
assert_eq!(opts.max_grpc_message_size, Some(16 * 1024 * 1024));
}
#[test]
fn client_options_with_keepalive_interval() {
let opts = ClientOptions::new().with_keepalive_interval(Duration::from_secs(30));
assert_eq!(opts.keepalive_interval, Some(Duration::from_secs(30)));
}
#[test]
fn client_options_with_keepalive_timeout() {
let opts = ClientOptions::new().with_keepalive_timeout(Duration::from_secs(10));
assert_eq!(opts.keepalive_timeout, Some(Duration::from_secs(10)));
}
#[test]
fn client_options_builder_chaining() {
let opts = ClientOptions::new()
.with_max_json_payload_size(2048)
.with_max_identifier_length(512)
.with_tls(TlsConfig::new().with_skip_verify())
.with_connect_timeout(Duration::from_secs(3))
.with_max_grpc_message_size(8 * 1024 * 1024)
.with_keepalive_interval(Duration::from_secs(60))
.with_keepalive_timeout(Duration::from_secs(20));
assert_eq!(opts.max_json_payload_size, 2048);
assert_eq!(opts.max_identifier_length, 512);
assert!(opts.tls.as_ref().unwrap().skip_verify);
assert_eq!(opts.connect_timeout, Some(Duration::from_secs(3)));
assert_eq!(opts.max_grpc_message_size, Some(8 * 1024 * 1024));
assert_eq!(opts.keepalive_interval, Some(Duration::from_secs(60)));
assert_eq!(opts.keepalive_timeout, Some(Duration::from_secs(20)));
}
}