use std::time::Duration;
use crate::limits::DEFAULT_PACKET_COUNT;
const DEFAULT_TIMEOUT_SECS: u64 = 300;
const DEFAULT_WRITE_BUFFER_SIZE: usize = 64 * 1024;
const DEFAULT_MAX_FILE_SIZE: u64 = 10 * 1024 * 1024 * 1024;
#[derive(Debug, Clone)]
pub struct ResourceLimits {
pub default_packet_count: u64,
pub timeout: Duration,
pub write_buffer_size: usize,
pub max_file_size: u64,
}
impl Default for ResourceLimits {
fn default() -> Self {
Self {
default_packet_count: DEFAULT_PACKET_COUNT,
timeout: Duration::from_secs(DEFAULT_TIMEOUT_SECS),
write_buffer_size: DEFAULT_WRITE_BUFFER_SIZE,
max_file_size: DEFAULT_MAX_FILE_SIZE,
}
}
}
impl ResourceLimits {
pub fn from_env() -> Self {
let defaults = Self::default();
Self {
default_packet_count: parse_env("DSCT_MCP_DEFAULT_COUNT")
.unwrap_or(defaults.default_packet_count),
timeout: parse_env::<u64>("DSCT_MCP_TIMEOUT")
.map(Duration::from_secs)
.unwrap_or(defaults.timeout),
write_buffer_size: parse_env("DSCT_MCP_WRITE_BUFFER_SIZE")
.unwrap_or(defaults.write_buffer_size),
max_file_size: parse_env("DSCT_MCP_MAX_FILE_SIZE").unwrap_or(defaults.max_file_size),
}
}
}
fn parse_env<T: std::str::FromStr>(key: &str) -> Option<T> {
std::env::var(key).ok()?.parse().ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_values() {
let limits = ResourceLimits::default();
assert_eq!(limits.default_packet_count, DEFAULT_PACKET_COUNT);
assert_eq!(limits.timeout, Duration::from_secs(300));
assert_eq!(limits.write_buffer_size, 64 * 1024);
}
#[test]
fn parse_env_returns_none_for_missing_var() {
let result = parse_env::<usize>("DSCT_TEST_NONEXISTENT_VAR_12345");
assert!(result.is_none());
}
#[test]
fn from_env_returns_defaults_in_clean_environment() {
let limits = ResourceLimits::from_env();
let defaults = ResourceLimits::default();
if std::env::var("DSCT_MCP_DEFAULT_COUNT").is_err() {
assert_eq!(limits.default_packet_count, defaults.default_packet_count);
}
if std::env::var("DSCT_MCP_TIMEOUT").is_err() {
assert_eq!(limits.timeout, defaults.timeout);
}
}
}