75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
use std::time::Duration;
|
|
|
|
pub struct Config {
|
|
pub token: String,
|
|
pub device_id: String,
|
|
pub base_url: String,
|
|
pub max_output_bytes: u64,
|
|
pub writer_channel_capacity: usize,
|
|
pub ping_interval: Duration,
|
|
pub ping_timeout: Duration,
|
|
}
|
|
|
|
impl Config {
|
|
const DEFAULT_BASE_URL: &str = "ws://127.0.0.1:8000";
|
|
const DEFAULT_DEVICE_ID: &str = "device";
|
|
const DEFAULT_MAX_OUTPUT_BYTES: u64 = 10 * 1024 * 1024;
|
|
const DEFAULT_WRITER_CHANNEL_CAPACITY: usize = 32;
|
|
const DEFAULT_PING_INTERVAL_SECS: u64 = 30;
|
|
const DEFAULT_PING_TIMEOUT_SECS: u64 = 10;
|
|
|
|
pub fn from_env() -> Result<Self, String> {
|
|
let token = std::env::var("TOKEN")
|
|
.map_err(|_| "TOKEN environment variable is required".to_string())?;
|
|
|
|
let device_id =
|
|
std::env::var("DEVICE_ID").unwrap_or_else(|_| Self::DEFAULT_DEVICE_ID.to_string());
|
|
validate_device_id(&device_id).map_err(|e| format!("Invalid DEVICE_ID: {e}"))?;
|
|
|
|
let base_url =
|
|
std::env::var("BASE_URL").unwrap_or_else(|_| Self::DEFAULT_BASE_URL.to_string());
|
|
|
|
Ok(Self {
|
|
token,
|
|
device_id,
|
|
base_url,
|
|
max_output_bytes: parse_env("MAX_OUTPUT_BYTES", Self::DEFAULT_MAX_OUTPUT_BYTES),
|
|
writer_channel_capacity: parse_env(
|
|
"WRITER_CHANNEL_CAPACITY",
|
|
Self::DEFAULT_WRITER_CHANNEL_CAPACITY,
|
|
),
|
|
ping_interval: Duration::from_secs(parse_env(
|
|
"PING_INTERVAL_SECS",
|
|
Self::DEFAULT_PING_INTERVAL_SECS,
|
|
)),
|
|
ping_timeout: Duration::from_secs(parse_env(
|
|
"PING_TIMEOUT_SECS",
|
|
Self::DEFAULT_PING_TIMEOUT_SECS,
|
|
)),
|
|
})
|
|
}
|
|
}
|
|
|
|
fn parse_env<T: std::str::FromStr>(key: &str, default: T) -> T {
|
|
std::env::var(key)
|
|
.ok()
|
|
.and_then(|v| v.parse().ok())
|
|
.unwrap_or(default)
|
|
}
|
|
|
|
fn validate_device_id(id: &str) -> Result<(), String> {
|
|
if id.is_empty() {
|
|
return Err("cannot be empty".into());
|
|
}
|
|
if id.len() > 64 {
|
|
return Err("too long (max 64 characters)".into());
|
|
}
|
|
if !id
|
|
.chars()
|
|
.all(|c| c.is_alphanumeric() || c == '-' || c == '_')
|
|
{
|
|
return Err("contains invalid characters (allowed: a-z A-Z 0-9 - _)".into());
|
|
}
|
|
Ok(())
|
|
}
|